binutils-gdb/gdb/eval.c

2928 lines
85 KiB
C
Raw Permalink Normal View History

/* Evaluate expressions for GDB.
Copyright (C) 1986-2024 Free Software Foundation, Inc.
1999-07-08 04:19:36 +08:00
This file is part of GDB.
1999-07-08 04:19:36 +08:00
This program 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 of the License, or
1999-07-08 04:19:36 +08:00
(at your option) any later version.
1999-07-08 04:19:36 +08:00
This program 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.
1999-07-08 04:19:36 +08:00
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
Revert the header-sorting patch Andreas Schwab and John Baldwin pointed out some bugs in the header sorting patch; and I noticed that the output was not correct when limited to a subset of files (a bug in my script). So, I'm reverting the patch. I may try again after fixing the issues pointed out. gdb/ChangeLog 2019-04-05 Tom Tromey <tom@tromey.com> Revert the header-sorting patch. * ft32-tdep.c: Revert. * frv-tdep.c: Revert. * frv-linux-tdep.c: Revert. * frame.c: Revert. * frame-unwind.c: Revert. * frame-base.c: Revert. * fork-child.c: Revert. * findvar.c: Revert. * findcmd.c: Revert. * filesystem.c: Revert. * filename-seen-cache.h: Revert. * filename-seen-cache.c: Revert. * fbsd-tdep.c: Revert. * fbsd-nat.h: Revert. * fbsd-nat.c: Revert. * f-valprint.c: Revert. * f-typeprint.c: Revert. * f-lang.c: Revert. * extension.h: Revert. * extension.c: Revert. * extension-priv.h: Revert. * expprint.c: Revert. * exec.h: Revert. * exec.c: Revert. * exceptions.c: Revert. * event-top.c: Revert. * event-loop.c: Revert. * eval.c: Revert. * elfread.c: Revert. * dwarf2read.h: Revert. * dwarf2read.c: Revert. * dwarf2loc.c: Revert. * dwarf2expr.h: Revert. * dwarf2expr.c: Revert. * dwarf2-frame.c: Revert. * dwarf2-frame-tailcall.c: Revert. * dwarf-index-write.h: Revert. * dwarf-index-write.c: Revert. * dwarf-index-common.c: Revert. * dwarf-index-cache.h: Revert. * dwarf-index-cache.c: Revert. * dummy-frame.c: Revert. * dtrace-probe.c: Revert. * disasm.h: Revert. * disasm.c: Revert. * disasm-selftests.c: Revert. * dictionary.c: Revert. * dicos-tdep.c: Revert. * demangle.c: Revert. * dcache.h: Revert. * dcache.c: Revert. * darwin-nat.h: Revert. * darwin-nat.c: Revert. * darwin-nat-info.c: Revert. * d-valprint.c: Revert. * d-namespace.c: Revert. * d-lang.c: Revert. * ctf.c: Revert. * csky-tdep.c: Revert. * csky-linux-tdep.c: Revert. * cris-tdep.c: Revert. * cris-linux-tdep.c: Revert. * cp-valprint.c: Revert. * cp-support.c: Revert. * cp-namespace.c: Revert. * cp-abi.c: Revert. * corelow.c: Revert. * corefile.c: Revert. * continuations.c: Revert. * completer.h: Revert. * completer.c: Revert. * complaints.c: Revert. * coffread.c: Revert. * coff-pe-read.c: Revert. * cli-out.h: Revert. * cli-out.c: Revert. * charset.c: Revert. * c-varobj.c: Revert. * c-valprint.c: Revert. * c-typeprint.c: Revert. * c-lang.c: Revert. * buildsym.c: Revert. * buildsym-legacy.c: Revert. * build-id.h: Revert. * build-id.c: Revert. * btrace.c: Revert. * bsd-uthread.c: Revert. * breakpoint.h: Revert. * breakpoint.c: Revert. * break-catch-throw.c: Revert. * break-catch-syscall.c: Revert. * break-catch-sig.c: Revert. * blockframe.c: Revert. * block.c: Revert. * bfin-tdep.c: Revert. * bfin-linux-tdep.c: Revert. * bfd-target.c: Revert. * bcache.c: Revert. * ax-general.c: Revert. * ax-gdb.h: Revert. * ax-gdb.c: Revert. * avr-tdep.c: Revert. * auxv.c: Revert. * auto-load.c: Revert. * arm-wince-tdep.c: Revert. * arm-tdep.c: Revert. * arm-symbian-tdep.c: Revert. * arm-pikeos-tdep.c: Revert. * arm-obsd-tdep.c: Revert. * arm-nbsd-tdep.c: Revert. * arm-nbsd-nat.c: Revert. * arm-linux-tdep.c: Revert. * arm-linux-nat.c: Revert. * arm-fbsd-tdep.c: Revert. * arm-fbsd-nat.c: Revert. * arm-bsd-tdep.c: Revert. * arch-utils.c: Revert. * arc-tdep.c: Revert. * arc-newlib-tdep.c: Revert. * annotate.h: Revert. * annotate.c: Revert. * amd64-windows-tdep.c: Revert. * amd64-windows-nat.c: Revert. * amd64-tdep.c: Revert. * amd64-sol2-tdep.c: Revert. * amd64-obsd-tdep.c: Revert. * amd64-obsd-nat.c: Revert. * amd64-nbsd-tdep.c: Revert. * amd64-nbsd-nat.c: Revert. * amd64-nat.c: Revert. * amd64-linux-tdep.c: Revert. * amd64-linux-nat.c: Revert. * amd64-fbsd-tdep.c: Revert. * amd64-fbsd-nat.c: Revert. * amd64-dicos-tdep.c: Revert. * amd64-darwin-tdep.c: Revert. * amd64-bsd-nat.c: Revert. * alpha-tdep.c: Revert. * alpha-obsd-tdep.c: Revert. * alpha-nbsd-tdep.c: Revert. * alpha-mdebug-tdep.c: Revert. * alpha-linux-tdep.c: Revert. * alpha-linux-nat.c: Revert. * alpha-bsd-tdep.c: Revert. * alpha-bsd-nat.c: Revert. * aix-thread.c: Revert. * agent.c: Revert. * addrmap.c: Revert. * ada-varobj.c: Revert. * ada-valprint.c: Revert. * ada-typeprint.c: Revert. * ada-tasks.c: Revert. * ada-lang.c: Revert. * aarch64-tdep.c: Revert. * aarch64-ravenscar-thread.c: Revert. * aarch64-newlib-tdep.c: Revert. * aarch64-linux-tdep.c: Revert. * aarch64-linux-nat.c: Revert. * aarch64-fbsd-tdep.c: Revert. * aarch64-fbsd-nat.c: Revert. * aarch32-linux-nat.c: Revert.
2019-04-07 03:38:10 +08:00
#include "symtab.h"
#include "gdbtypes.h"
#include "value.h"
#include "expression.h"
Revert the header-sorting patch Andreas Schwab and John Baldwin pointed out some bugs in the header sorting patch; and I noticed that the output was not correct when limited to a subset of files (a bug in my script). So, I'm reverting the patch. I may try again after fixing the issues pointed out. gdb/ChangeLog 2019-04-05 Tom Tromey <tom@tromey.com> Revert the header-sorting patch. * ft32-tdep.c: Revert. * frv-tdep.c: Revert. * frv-linux-tdep.c: Revert. * frame.c: Revert. * frame-unwind.c: Revert. * frame-base.c: Revert. * fork-child.c: Revert. * findvar.c: Revert. * findcmd.c: Revert. * filesystem.c: Revert. * filename-seen-cache.h: Revert. * filename-seen-cache.c: Revert. * fbsd-tdep.c: Revert. * fbsd-nat.h: Revert. * fbsd-nat.c: Revert. * f-valprint.c: Revert. * f-typeprint.c: Revert. * f-lang.c: Revert. * extension.h: Revert. * extension.c: Revert. * extension-priv.h: Revert. * expprint.c: Revert. * exec.h: Revert. * exec.c: Revert. * exceptions.c: Revert. * event-top.c: Revert. * event-loop.c: Revert. * eval.c: Revert. * elfread.c: Revert. * dwarf2read.h: Revert. * dwarf2read.c: Revert. * dwarf2loc.c: Revert. * dwarf2expr.h: Revert. * dwarf2expr.c: Revert. * dwarf2-frame.c: Revert. * dwarf2-frame-tailcall.c: Revert. * dwarf-index-write.h: Revert. * dwarf-index-write.c: Revert. * dwarf-index-common.c: Revert. * dwarf-index-cache.h: Revert. * dwarf-index-cache.c: Revert. * dummy-frame.c: Revert. * dtrace-probe.c: Revert. * disasm.h: Revert. * disasm.c: Revert. * disasm-selftests.c: Revert. * dictionary.c: Revert. * dicos-tdep.c: Revert. * demangle.c: Revert. * dcache.h: Revert. * dcache.c: Revert. * darwin-nat.h: Revert. * darwin-nat.c: Revert. * darwin-nat-info.c: Revert. * d-valprint.c: Revert. * d-namespace.c: Revert. * d-lang.c: Revert. * ctf.c: Revert. * csky-tdep.c: Revert. * csky-linux-tdep.c: Revert. * cris-tdep.c: Revert. * cris-linux-tdep.c: Revert. * cp-valprint.c: Revert. * cp-support.c: Revert. * cp-namespace.c: Revert. * cp-abi.c: Revert. * corelow.c: Revert. * corefile.c: Revert. * continuations.c: Revert. * completer.h: Revert. * completer.c: Revert. * complaints.c: Revert. * coffread.c: Revert. * coff-pe-read.c: Revert. * cli-out.h: Revert. * cli-out.c: Revert. * charset.c: Revert. * c-varobj.c: Revert. * c-valprint.c: Revert. * c-typeprint.c: Revert. * c-lang.c: Revert. * buildsym.c: Revert. * buildsym-legacy.c: Revert. * build-id.h: Revert. * build-id.c: Revert. * btrace.c: Revert. * bsd-uthread.c: Revert. * breakpoint.h: Revert. * breakpoint.c: Revert. * break-catch-throw.c: Revert. * break-catch-syscall.c: Revert. * break-catch-sig.c: Revert. * blockframe.c: Revert. * block.c: Revert. * bfin-tdep.c: Revert. * bfin-linux-tdep.c: Revert. * bfd-target.c: Revert. * bcache.c: Revert. * ax-general.c: Revert. * ax-gdb.h: Revert. * ax-gdb.c: Revert. * avr-tdep.c: Revert. * auxv.c: Revert. * auto-load.c: Revert. * arm-wince-tdep.c: Revert. * arm-tdep.c: Revert. * arm-symbian-tdep.c: Revert. * arm-pikeos-tdep.c: Revert. * arm-obsd-tdep.c: Revert. * arm-nbsd-tdep.c: Revert. * arm-nbsd-nat.c: Revert. * arm-linux-tdep.c: Revert. * arm-linux-nat.c: Revert. * arm-fbsd-tdep.c: Revert. * arm-fbsd-nat.c: Revert. * arm-bsd-tdep.c: Revert. * arch-utils.c: Revert. * arc-tdep.c: Revert. * arc-newlib-tdep.c: Revert. * annotate.h: Revert. * annotate.c: Revert. * amd64-windows-tdep.c: Revert. * amd64-windows-nat.c: Revert. * amd64-tdep.c: Revert. * amd64-sol2-tdep.c: Revert. * amd64-obsd-tdep.c: Revert. * amd64-obsd-nat.c: Revert. * amd64-nbsd-tdep.c: Revert. * amd64-nbsd-nat.c: Revert. * amd64-nat.c: Revert. * amd64-linux-tdep.c: Revert. * amd64-linux-nat.c: Revert. * amd64-fbsd-tdep.c: Revert. * amd64-fbsd-nat.c: Revert. * amd64-dicos-tdep.c: Revert. * amd64-darwin-tdep.c: Revert. * amd64-bsd-nat.c: Revert. * alpha-tdep.c: Revert. * alpha-obsd-tdep.c: Revert. * alpha-nbsd-tdep.c: Revert. * alpha-mdebug-tdep.c: Revert. * alpha-linux-tdep.c: Revert. * alpha-linux-nat.c: Revert. * alpha-bsd-tdep.c: Revert. * alpha-bsd-nat.c: Revert. * aix-thread.c: Revert. * agent.c: Revert. * addrmap.c: Revert. * ada-varobj.c: Revert. * ada-valprint.c: Revert. * ada-typeprint.c: Revert. * ada-tasks.c: Revert. * ada-lang.c: Revert. * aarch64-tdep.c: Revert. * aarch64-ravenscar-thread.c: Revert. * aarch64-newlib-tdep.c: Revert. * aarch64-linux-tdep.c: Revert. * aarch64-linux-nat.c: Revert. * aarch64-fbsd-tdep.c: Revert. * aarch64-fbsd-nat.c: Revert. * aarch32-linux-nat.c: Revert.
2019-04-07 03:38:10 +08:00
#include "target.h"
#include "frame.h"
#include "gdbthread.h"
#include "language.h"
Revert the header-sorting patch Andreas Schwab and John Baldwin pointed out some bugs in the header sorting patch; and I noticed that the output was not correct when limited to a subset of files (a bug in my script). So, I'm reverting the patch. I may try again after fixing the issues pointed out. gdb/ChangeLog 2019-04-05 Tom Tromey <tom@tromey.com> Revert the header-sorting patch. * ft32-tdep.c: Revert. * frv-tdep.c: Revert. * frv-linux-tdep.c: Revert. * frame.c: Revert. * frame-unwind.c: Revert. * frame-base.c: Revert. * fork-child.c: Revert. * findvar.c: Revert. * findcmd.c: Revert. * filesystem.c: Revert. * filename-seen-cache.h: Revert. * filename-seen-cache.c: Revert. * fbsd-tdep.c: Revert. * fbsd-nat.h: Revert. * fbsd-nat.c: Revert. * f-valprint.c: Revert. * f-typeprint.c: Revert. * f-lang.c: Revert. * extension.h: Revert. * extension.c: Revert. * extension-priv.h: Revert. * expprint.c: Revert. * exec.h: Revert. * exec.c: Revert. * exceptions.c: Revert. * event-top.c: Revert. * event-loop.c: Revert. * eval.c: Revert. * elfread.c: Revert. * dwarf2read.h: Revert. * dwarf2read.c: Revert. * dwarf2loc.c: Revert. * dwarf2expr.h: Revert. * dwarf2expr.c: Revert. * dwarf2-frame.c: Revert. * dwarf2-frame-tailcall.c: Revert. * dwarf-index-write.h: Revert. * dwarf-index-write.c: Revert. * dwarf-index-common.c: Revert. * dwarf-index-cache.h: Revert. * dwarf-index-cache.c: Revert. * dummy-frame.c: Revert. * dtrace-probe.c: Revert. * disasm.h: Revert. * disasm.c: Revert. * disasm-selftests.c: Revert. * dictionary.c: Revert. * dicos-tdep.c: Revert. * demangle.c: Revert. * dcache.h: Revert. * dcache.c: Revert. * darwin-nat.h: Revert. * darwin-nat.c: Revert. * darwin-nat-info.c: Revert. * d-valprint.c: Revert. * d-namespace.c: Revert. * d-lang.c: Revert. * ctf.c: Revert. * csky-tdep.c: Revert. * csky-linux-tdep.c: Revert. * cris-tdep.c: Revert. * cris-linux-tdep.c: Revert. * cp-valprint.c: Revert. * cp-support.c: Revert. * cp-namespace.c: Revert. * cp-abi.c: Revert. * corelow.c: Revert. * corefile.c: Revert. * continuations.c: Revert. * completer.h: Revert. * completer.c: Revert. * complaints.c: Revert. * coffread.c: Revert. * coff-pe-read.c: Revert. * cli-out.h: Revert. * cli-out.c: Revert. * charset.c: Revert. * c-varobj.c: Revert. * c-valprint.c: Revert. * c-typeprint.c: Revert. * c-lang.c: Revert. * buildsym.c: Revert. * buildsym-legacy.c: Revert. * build-id.h: Revert. * build-id.c: Revert. * btrace.c: Revert. * bsd-uthread.c: Revert. * breakpoint.h: Revert. * breakpoint.c: Revert. * break-catch-throw.c: Revert. * break-catch-syscall.c: Revert. * break-catch-sig.c: Revert. * blockframe.c: Revert. * block.c: Revert. * bfin-tdep.c: Revert. * bfin-linux-tdep.c: Revert. * bfd-target.c: Revert. * bcache.c: Revert. * ax-general.c: Revert. * ax-gdb.h: Revert. * ax-gdb.c: Revert. * avr-tdep.c: Revert. * auxv.c: Revert. * auto-load.c: Revert. * arm-wince-tdep.c: Revert. * arm-tdep.c: Revert. * arm-symbian-tdep.c: Revert. * arm-pikeos-tdep.c: Revert. * arm-obsd-tdep.c: Revert. * arm-nbsd-tdep.c: Revert. * arm-nbsd-nat.c: Revert. * arm-linux-tdep.c: Revert. * arm-linux-nat.c: Revert. * arm-fbsd-tdep.c: Revert. * arm-fbsd-nat.c: Revert. * arm-bsd-tdep.c: Revert. * arch-utils.c: Revert. * arc-tdep.c: Revert. * arc-newlib-tdep.c: Revert. * annotate.h: Revert. * annotate.c: Revert. * amd64-windows-tdep.c: Revert. * amd64-windows-nat.c: Revert. * amd64-tdep.c: Revert. * amd64-sol2-tdep.c: Revert. * amd64-obsd-tdep.c: Revert. * amd64-obsd-nat.c: Revert. * amd64-nbsd-tdep.c: Revert. * amd64-nbsd-nat.c: Revert. * amd64-nat.c: Revert. * amd64-linux-tdep.c: Revert. * amd64-linux-nat.c: Revert. * amd64-fbsd-tdep.c: Revert. * amd64-fbsd-nat.c: Revert. * amd64-dicos-tdep.c: Revert. * amd64-darwin-tdep.c: Revert. * amd64-bsd-nat.c: Revert. * alpha-tdep.c: Revert. * alpha-obsd-tdep.c: Revert. * alpha-nbsd-tdep.c: Revert. * alpha-mdebug-tdep.c: Revert. * alpha-linux-tdep.c: Revert. * alpha-linux-nat.c: Revert. * alpha-bsd-tdep.c: Revert. * alpha-bsd-nat.c: Revert. * aix-thread.c: Revert. * agent.c: Revert. * addrmap.c: Revert. * ada-varobj.c: Revert. * ada-valprint.c: Revert. * ada-typeprint.c: Revert. * ada-tasks.c: Revert. * ada-lang.c: Revert. * aarch64-tdep.c: Revert. * aarch64-ravenscar-thread.c: Revert. * aarch64-newlib-tdep.c: Revert. * aarch64-linux-tdep.c: Revert. * aarch64-linux-nat.c: Revert. * aarch64-fbsd-tdep.c: Revert. * aarch64-fbsd-nat.c: Revert. * aarch32-linux-nat.c: Revert.
2019-04-07 03:38:10 +08:00
#include "cp-abi.h"
2003-04-22 00:48:41 +08:00
#include "infcall.h"
#include "objc-lang.h"
Revert the header-sorting patch Andreas Schwab and John Baldwin pointed out some bugs in the header sorting patch; and I noticed that the output was not correct when limited to a subset of files (a bug in my script). So, I'm reverting the patch. I may try again after fixing the issues pointed out. gdb/ChangeLog 2019-04-05 Tom Tromey <tom@tromey.com> Revert the header-sorting patch. * ft32-tdep.c: Revert. * frv-tdep.c: Revert. * frv-linux-tdep.c: Revert. * frame.c: Revert. * frame-unwind.c: Revert. * frame-base.c: Revert. * fork-child.c: Revert. * findvar.c: Revert. * findcmd.c: Revert. * filesystem.c: Revert. * filename-seen-cache.h: Revert. * filename-seen-cache.c: Revert. * fbsd-tdep.c: Revert. * fbsd-nat.h: Revert. * fbsd-nat.c: Revert. * f-valprint.c: Revert. * f-typeprint.c: Revert. * f-lang.c: Revert. * extension.h: Revert. * extension.c: Revert. * extension-priv.h: Revert. * expprint.c: Revert. * exec.h: Revert. * exec.c: Revert. * exceptions.c: Revert. * event-top.c: Revert. * event-loop.c: Revert. * eval.c: Revert. * elfread.c: Revert. * dwarf2read.h: Revert. * dwarf2read.c: Revert. * dwarf2loc.c: Revert. * dwarf2expr.h: Revert. * dwarf2expr.c: Revert. * dwarf2-frame.c: Revert. * dwarf2-frame-tailcall.c: Revert. * dwarf-index-write.h: Revert. * dwarf-index-write.c: Revert. * dwarf-index-common.c: Revert. * dwarf-index-cache.h: Revert. * dwarf-index-cache.c: Revert. * dummy-frame.c: Revert. * dtrace-probe.c: Revert. * disasm.h: Revert. * disasm.c: Revert. * disasm-selftests.c: Revert. * dictionary.c: Revert. * dicos-tdep.c: Revert. * demangle.c: Revert. * dcache.h: Revert. * dcache.c: Revert. * darwin-nat.h: Revert. * darwin-nat.c: Revert. * darwin-nat-info.c: Revert. * d-valprint.c: Revert. * d-namespace.c: Revert. * d-lang.c: Revert. * ctf.c: Revert. * csky-tdep.c: Revert. * csky-linux-tdep.c: Revert. * cris-tdep.c: Revert. * cris-linux-tdep.c: Revert. * cp-valprint.c: Revert. * cp-support.c: Revert. * cp-namespace.c: Revert. * cp-abi.c: Revert. * corelow.c: Revert. * corefile.c: Revert. * continuations.c: Revert. * completer.h: Revert. * completer.c: Revert. * complaints.c: Revert. * coffread.c: Revert. * coff-pe-read.c: Revert. * cli-out.h: Revert. * cli-out.c: Revert. * charset.c: Revert. * c-varobj.c: Revert. * c-valprint.c: Revert. * c-typeprint.c: Revert. * c-lang.c: Revert. * buildsym.c: Revert. * buildsym-legacy.c: Revert. * build-id.h: Revert. * build-id.c: Revert. * btrace.c: Revert. * bsd-uthread.c: Revert. * breakpoint.h: Revert. * breakpoint.c: Revert. * break-catch-throw.c: Revert. * break-catch-syscall.c: Revert. * break-catch-sig.c: Revert. * blockframe.c: Revert. * block.c: Revert. * bfin-tdep.c: Revert. * bfin-linux-tdep.c: Revert. * bfd-target.c: Revert. * bcache.c: Revert. * ax-general.c: Revert. * ax-gdb.h: Revert. * ax-gdb.c: Revert. * avr-tdep.c: Revert. * auxv.c: Revert. * auto-load.c: Revert. * arm-wince-tdep.c: Revert. * arm-tdep.c: Revert. * arm-symbian-tdep.c: Revert. * arm-pikeos-tdep.c: Revert. * arm-obsd-tdep.c: Revert. * arm-nbsd-tdep.c: Revert. * arm-nbsd-nat.c: Revert. * arm-linux-tdep.c: Revert. * arm-linux-nat.c: Revert. * arm-fbsd-tdep.c: Revert. * arm-fbsd-nat.c: Revert. * arm-bsd-tdep.c: Revert. * arch-utils.c: Revert. * arc-tdep.c: Revert. * arc-newlib-tdep.c: Revert. * annotate.h: Revert. * annotate.c: Revert. * amd64-windows-tdep.c: Revert. * amd64-windows-nat.c: Revert. * amd64-tdep.c: Revert. * amd64-sol2-tdep.c: Revert. * amd64-obsd-tdep.c: Revert. * amd64-obsd-nat.c: Revert. * amd64-nbsd-tdep.c: Revert. * amd64-nbsd-nat.c: Revert. * amd64-nat.c: Revert. * amd64-linux-tdep.c: Revert. * amd64-linux-nat.c: Revert. * amd64-fbsd-tdep.c: Revert. * amd64-fbsd-nat.c: Revert. * amd64-dicos-tdep.c: Revert. * amd64-darwin-tdep.c: Revert. * amd64-bsd-nat.c: Revert. * alpha-tdep.c: Revert. * alpha-obsd-tdep.c: Revert. * alpha-nbsd-tdep.c: Revert. * alpha-mdebug-tdep.c: Revert. * alpha-linux-tdep.c: Revert. * alpha-linux-nat.c: Revert. * alpha-bsd-tdep.c: Revert. * alpha-bsd-nat.c: Revert. * aix-thread.c: Revert. * agent.c: Revert. * addrmap.c: Revert. * ada-varobj.c: Revert. * ada-valprint.c: Revert. * ada-typeprint.c: Revert. * ada-tasks.c: Revert. * ada-lang.c: Revert. * aarch64-tdep.c: Revert. * aarch64-ravenscar-thread.c: Revert. * aarch64-newlib-tdep.c: Revert. * aarch64-linux-tdep.c: Revert. * aarch64-linux-nat.c: Revert. * aarch64-fbsd-tdep.c: Revert. * aarch64-fbsd-nat.c: Revert. * aarch32-linux-nat.c: Revert.
2019-04-07 03:38:10 +08:00
#include "block.h"
* parser-defs.h (struct exp_descriptor): New definition, containing language-specific info for printing, prefixifying, dumping, and evaluating expressions. (exp_descriptor_standard): Declare new variable. (print_subexp): Make global and declare here (from expprint.c). (dump_subexp): Ditto. (dump_subexp_body_standard): Declare. (operator_length_standard): Declare. (op_name_standard): Declare. (print_subexp): Declare. (print_subexp_standard): Declare. * language.h (struct language_defn): Add la_exp_desc field to hold pointer to table for language-specific operators. Remove evaluate_exp field, which is now in struct exp_descriptor. * parse.c (operator_length): Move most code to new operator_length_standard function. Use language-specific information. (operator_length_standard): New function taking most code from operator_length. (exp_descriptor_standard): New constant. * expression.h (enum exp_opcode): Add definitions of OP_EXTENDED0 and OP_EXTENDED_LAST. * expprint.c (print_subexp): Use language-specific print_subexp. Make global; remove static declaration. Move most code to print_subexp_standard. (print_subexp_standard): New function, containing code formerly in print_subexp. (op_name): Add expression to argument signature. Use langauge-specific op_name. Move most code to op_name_standard. (op_name_standard): New function, containing code formerly in op_name. (dump_subexp): Use new version of op_name function. Use language-specific dump_subexp_body, and move most existing code to dump_subexp_body_standard. (dump_raw_expression): Use new op_name interface. (dump_subexp_body): Move most code to dump_subexp_body_standard. (dump_subexp_body_standard): New function, containing code formerly in dump_subexp_body. * language.c (unknown_language): Add default la_exp_desc field and remove evaluate_exp field. (auto_language): Ditto. (local_language): Ditto. * f-lang.c (f_language_defn): Ditto. * c-lang.c (c_language_defn): Ditto. (cplus_language_defn): Ditto. (asm_language_defn): Ditto. (minimal_language_defn): Ditto. * p-lang.c (pascal_language_defn): Ditto. * m2-lang.c (m2_language_defn): Ditto. * objc-lang.c (objc_language_defn): Ditto. * jv-lang.c (exp_descriptor_java): New variable, containing Java-specific expression evaluator. (java_language_defn): Add la_exp_desc field and remove evaluate_exp field. * scm-lang.c (exp_descriptor_scm): New variable, containing Scheme-specific expression evaluator. (scm_language_defn): Add la_exp_desc field and remove evaluate_exp field. * objc-lang.c (print_object_command): Take evaluate_exp from the la_exp_desc field. * Makefile.in (eval.o): Add dependency on parser-defs.h. * eval.c: Include parser-defs.h for the full declaration of la_exp_desc's type. (evaluate_subexp): Get evaluate_exp out of la_exp_desc field.
2003-09-25 16:40:45 +08:00
#include "parser-defs.h"
Revert the header-sorting patch Andreas Schwab and John Baldwin pointed out some bugs in the header sorting patch; and I noticed that the output was not correct when limited to a subset of files (a bug in my script). So, I'm reverting the patch. I may try again after fixing the issues pointed out. gdb/ChangeLog 2019-04-05 Tom Tromey <tom@tromey.com> Revert the header-sorting patch. * ft32-tdep.c: Revert. * frv-tdep.c: Revert. * frv-linux-tdep.c: Revert. * frame.c: Revert. * frame-unwind.c: Revert. * frame-base.c: Revert. * fork-child.c: Revert. * findvar.c: Revert. * findcmd.c: Revert. * filesystem.c: Revert. * filename-seen-cache.h: Revert. * filename-seen-cache.c: Revert. * fbsd-tdep.c: Revert. * fbsd-nat.h: Revert. * fbsd-nat.c: Revert. * f-valprint.c: Revert. * f-typeprint.c: Revert. * f-lang.c: Revert. * extension.h: Revert. * extension.c: Revert. * extension-priv.h: Revert. * expprint.c: Revert. * exec.h: Revert. * exec.c: Revert. * exceptions.c: Revert. * event-top.c: Revert. * event-loop.c: Revert. * eval.c: Revert. * elfread.c: Revert. * dwarf2read.h: Revert. * dwarf2read.c: Revert. * dwarf2loc.c: Revert. * dwarf2expr.h: Revert. * dwarf2expr.c: Revert. * dwarf2-frame.c: Revert. * dwarf2-frame-tailcall.c: Revert. * dwarf-index-write.h: Revert. * dwarf-index-write.c: Revert. * dwarf-index-common.c: Revert. * dwarf-index-cache.h: Revert. * dwarf-index-cache.c: Revert. * dummy-frame.c: Revert. * dtrace-probe.c: Revert. * disasm.h: Revert. * disasm.c: Revert. * disasm-selftests.c: Revert. * dictionary.c: Revert. * dicos-tdep.c: Revert. * demangle.c: Revert. * dcache.h: Revert. * dcache.c: Revert. * darwin-nat.h: Revert. * darwin-nat.c: Revert. * darwin-nat-info.c: Revert. * d-valprint.c: Revert. * d-namespace.c: Revert. * d-lang.c: Revert. * ctf.c: Revert. * csky-tdep.c: Revert. * csky-linux-tdep.c: Revert. * cris-tdep.c: Revert. * cris-linux-tdep.c: Revert. * cp-valprint.c: Revert. * cp-support.c: Revert. * cp-namespace.c: Revert. * cp-abi.c: Revert. * corelow.c: Revert. * corefile.c: Revert. * continuations.c: Revert. * completer.h: Revert. * completer.c: Revert. * complaints.c: Revert. * coffread.c: Revert. * coff-pe-read.c: Revert. * cli-out.h: Revert. * cli-out.c: Revert. * charset.c: Revert. * c-varobj.c: Revert. * c-valprint.c: Revert. * c-typeprint.c: Revert. * c-lang.c: Revert. * buildsym.c: Revert. * buildsym-legacy.c: Revert. * build-id.h: Revert. * build-id.c: Revert. * btrace.c: Revert. * bsd-uthread.c: Revert. * breakpoint.h: Revert. * breakpoint.c: Revert. * break-catch-throw.c: Revert. * break-catch-syscall.c: Revert. * break-catch-sig.c: Revert. * blockframe.c: Revert. * block.c: Revert. * bfin-tdep.c: Revert. * bfin-linux-tdep.c: Revert. * bfd-target.c: Revert. * bcache.c: Revert. * ax-general.c: Revert. * ax-gdb.h: Revert. * ax-gdb.c: Revert. * avr-tdep.c: Revert. * auxv.c: Revert. * auto-load.c: Revert. * arm-wince-tdep.c: Revert. * arm-tdep.c: Revert. * arm-symbian-tdep.c: Revert. * arm-pikeos-tdep.c: Revert. * arm-obsd-tdep.c: Revert. * arm-nbsd-tdep.c: Revert. * arm-nbsd-nat.c: Revert. * arm-linux-tdep.c: Revert. * arm-linux-nat.c: Revert. * arm-fbsd-tdep.c: Revert. * arm-fbsd-nat.c: Revert. * arm-bsd-tdep.c: Revert. * arch-utils.c: Revert. * arc-tdep.c: Revert. * arc-newlib-tdep.c: Revert. * annotate.h: Revert. * annotate.c: Revert. * amd64-windows-tdep.c: Revert. * amd64-windows-nat.c: Revert. * amd64-tdep.c: Revert. * amd64-sol2-tdep.c: Revert. * amd64-obsd-tdep.c: Revert. * amd64-obsd-nat.c: Revert. * amd64-nbsd-tdep.c: Revert. * amd64-nbsd-nat.c: Revert. * amd64-nat.c: Revert. * amd64-linux-tdep.c: Revert. * amd64-linux-nat.c: Revert. * amd64-fbsd-tdep.c: Revert. * amd64-fbsd-nat.c: Revert. * amd64-dicos-tdep.c: Revert. * amd64-darwin-tdep.c: Revert. * amd64-bsd-nat.c: Revert. * alpha-tdep.c: Revert. * alpha-obsd-tdep.c: Revert. * alpha-nbsd-tdep.c: Revert. * alpha-mdebug-tdep.c: Revert. * alpha-linux-tdep.c: Revert. * alpha-linux-nat.c: Revert. * alpha-bsd-tdep.c: Revert. * alpha-bsd-nat.c: Revert. * aix-thread.c: Revert. * agent.c: Revert. * addrmap.c: Revert. * ada-varobj.c: Revert. * ada-valprint.c: Revert. * ada-typeprint.c: Revert. * ada-tasks.c: Revert. * ada-lang.c: Revert. * aarch64-tdep.c: Revert. * aarch64-ravenscar-thread.c: Revert. * aarch64-newlib-tdep.c: Revert. * aarch64-linux-tdep.c: Revert. * aarch64-linux-nat.c: Revert. * aarch64-fbsd-tdep.c: Revert. * aarch64-fbsd-nat.c: Revert. * aarch32-linux-nat.c: Revert.
2019-04-07 03:38:10 +08:00
#include "cp-support.h"
Sort includes for files gdb/[a-f]*.[chyl]. This patch sorts the include files for the files [a-f]*.[chyl]. The patch was written by a script. Tested by the buildbot. I will follow up with patches to sort the remaining files, by sorting a subset, testing them, and then checking them in. gdb/ChangeLog 2019-04-05 Tom Tromey <tom@tromey.com> * ft32-tdep.c: Sort headers. * frv-tdep.c: Sort headers. * frv-linux-tdep.c: Sort headers. * frame.c: Sort headers. * frame-unwind.c: Sort headers. * frame-base.c: Sort headers. * fork-child.c: Sort headers. * findvar.c: Sort headers. * findcmd.c: Sort headers. * filesystem.c: Sort headers. * filename-seen-cache.h: Sort headers. * filename-seen-cache.c: Sort headers. * fbsd-tdep.c: Sort headers. * fbsd-nat.h: Sort headers. * fbsd-nat.c: Sort headers. * f-valprint.c: Sort headers. * f-typeprint.c: Sort headers. * f-lang.c: Sort headers. * extension.h: Sort headers. * extension.c: Sort headers. * extension-priv.h: Sort headers. * expprint.c: Sort headers. * exec.h: Sort headers. * exec.c: Sort headers. * exceptions.c: Sort headers. * event-top.c: Sort headers. * event-loop.c: Sort headers. * eval.c: Sort headers. * elfread.c: Sort headers. * dwarf2read.h: Sort headers. * dwarf2read.c: Sort headers. * dwarf2loc.c: Sort headers. * dwarf2expr.h: Sort headers. * dwarf2expr.c: Sort headers. * dwarf2-frame.c: Sort headers. * dwarf2-frame-tailcall.c: Sort headers. * dwarf-index-write.h: Sort headers. * dwarf-index-write.c: Sort headers. * dwarf-index-common.c: Sort headers. * dwarf-index-cache.h: Sort headers. * dwarf-index-cache.c: Sort headers. * dummy-frame.c: Sort headers. * dtrace-probe.c: Sort headers. * disasm.h: Sort headers. * disasm.c: Sort headers. * disasm-selftests.c: Sort headers. * dictionary.c: Sort headers. * dicos-tdep.c: Sort headers. * demangle.c: Sort headers. * dcache.h: Sort headers. * dcache.c: Sort headers. * darwin-nat.h: Sort headers. * darwin-nat.c: Sort headers. * darwin-nat-info.c: Sort headers. * d-valprint.c: Sort headers. * d-namespace.c: Sort headers. * d-lang.c: Sort headers. * ctf.c: Sort headers. * csky-tdep.c: Sort headers. * csky-linux-tdep.c: Sort headers. * cris-tdep.c: Sort headers. * cris-linux-tdep.c: Sort headers. * cp-valprint.c: Sort headers. * cp-support.c: Sort headers. * cp-namespace.c: Sort headers. * cp-abi.c: Sort headers. * corelow.c: Sort headers. * corefile.c: Sort headers. * continuations.c: Sort headers. * completer.h: Sort headers. * completer.c: Sort headers. * complaints.c: Sort headers. * coffread.c: Sort headers. * coff-pe-read.c: Sort headers. * cli-out.h: Sort headers. * cli-out.c: Sort headers. * charset.c: Sort headers. * c-varobj.c: Sort headers. * c-valprint.c: Sort headers. * c-typeprint.c: Sort headers. * c-lang.c: Sort headers. * buildsym.c: Sort headers. * buildsym-legacy.c: Sort headers. * build-id.h: Sort headers. * build-id.c: Sort headers. * btrace.c: Sort headers. * bsd-uthread.c: Sort headers. * breakpoint.h: Sort headers. * breakpoint.c: Sort headers. * break-catch-throw.c: Sort headers. * break-catch-syscall.c: Sort headers. * break-catch-sig.c: Sort headers. * blockframe.c: Sort headers. * block.c: Sort headers. * bfin-tdep.c: Sort headers. * bfin-linux-tdep.c: Sort headers. * bfd-target.c: Sort headers. * bcache.c: Sort headers. * ax-general.c: Sort headers. * ax-gdb.h: Sort headers. * ax-gdb.c: Sort headers. * avr-tdep.c: Sort headers. * auxv.c: Sort headers. * auto-load.c: Sort headers. * arm-wince-tdep.c: Sort headers. * arm-tdep.c: Sort headers. * arm-symbian-tdep.c: Sort headers. * arm-pikeos-tdep.c: Sort headers. * arm-obsd-tdep.c: Sort headers. * arm-nbsd-tdep.c: Sort headers. * arm-nbsd-nat.c: Sort headers. * arm-linux-tdep.c: Sort headers. * arm-linux-nat.c: Sort headers. * arm-fbsd-tdep.c: Sort headers. * arm-fbsd-nat.c: Sort headers. * arm-bsd-tdep.c: Sort headers. * arch-utils.c: Sort headers. * arc-tdep.c: Sort headers. * arc-newlib-tdep.c: Sort headers. * annotate.h: Sort headers. * annotate.c: Sort headers. * amd64-windows-tdep.c: Sort headers. * amd64-windows-nat.c: Sort headers. * amd64-tdep.c: Sort headers. * amd64-sol2-tdep.c: Sort headers. * amd64-obsd-tdep.c: Sort headers. * amd64-obsd-nat.c: Sort headers. * amd64-nbsd-tdep.c: Sort headers. * amd64-nbsd-nat.c: Sort headers. * amd64-nat.c: Sort headers. * amd64-linux-tdep.c: Sort headers. * amd64-linux-nat.c: Sort headers. * amd64-fbsd-tdep.c: Sort headers. * amd64-fbsd-nat.c: Sort headers. * amd64-dicos-tdep.c: Sort headers. * amd64-darwin-tdep.c: Sort headers. * amd64-bsd-nat.c: Sort headers. * alpha-tdep.c: Sort headers. * alpha-obsd-tdep.c: Sort headers. * alpha-nbsd-tdep.c: Sort headers. * alpha-mdebug-tdep.c: Sort headers. * alpha-linux-tdep.c: Sort headers. * alpha-linux-nat.c: Sort headers. * alpha-bsd-tdep.c: Sort headers. * alpha-bsd-nat.c: Sort headers. * aix-thread.c: Sort headers. * agent.c: Sort headers. * addrmap.c: Sort headers. * ada-varobj.c: Sort headers. * ada-valprint.c: Sort headers. * ada-typeprint.c: Sort headers. * ada-tasks.c: Sort headers. * ada-lang.c: Sort headers. * aarch64-tdep.c: Sort headers. * aarch64-ravenscar-thread.c: Sort headers. * aarch64-newlib-tdep.c: Sort headers. * aarch64-linux-tdep.c: Sort headers. * aarch64-linux-nat.c: Sort headers. * aarch64-fbsd-tdep.c: Sort headers. * aarch64-fbsd-nat.c: Sort headers. * aarch32-linux-nat.c: Sort headers.
2019-04-03 10:04:24 +08:00
#include "ui-out.h"
Revert the header-sorting patch Andreas Schwab and John Baldwin pointed out some bugs in the header sorting patch; and I noticed that the output was not correct when limited to a subset of files (a bug in my script). So, I'm reverting the patch. I may try again after fixing the issues pointed out. gdb/ChangeLog 2019-04-05 Tom Tromey <tom@tromey.com> Revert the header-sorting patch. * ft32-tdep.c: Revert. * frv-tdep.c: Revert. * frv-linux-tdep.c: Revert. * frame.c: Revert. * frame-unwind.c: Revert. * frame-base.c: Revert. * fork-child.c: Revert. * findvar.c: Revert. * findcmd.c: Revert. * filesystem.c: Revert. * filename-seen-cache.h: Revert. * filename-seen-cache.c: Revert. * fbsd-tdep.c: Revert. * fbsd-nat.h: Revert. * fbsd-nat.c: Revert. * f-valprint.c: Revert. * f-typeprint.c: Revert. * f-lang.c: Revert. * extension.h: Revert. * extension.c: Revert. * extension-priv.h: Revert. * expprint.c: Revert. * exec.h: Revert. * exec.c: Revert. * exceptions.c: Revert. * event-top.c: Revert. * event-loop.c: Revert. * eval.c: Revert. * elfread.c: Revert. * dwarf2read.h: Revert. * dwarf2read.c: Revert. * dwarf2loc.c: Revert. * dwarf2expr.h: Revert. * dwarf2expr.c: Revert. * dwarf2-frame.c: Revert. * dwarf2-frame-tailcall.c: Revert. * dwarf-index-write.h: Revert. * dwarf-index-write.c: Revert. * dwarf-index-common.c: Revert. * dwarf-index-cache.h: Revert. * dwarf-index-cache.c: Revert. * dummy-frame.c: Revert. * dtrace-probe.c: Revert. * disasm.h: Revert. * disasm.c: Revert. * disasm-selftests.c: Revert. * dictionary.c: Revert. * dicos-tdep.c: Revert. * demangle.c: Revert. * dcache.h: Revert. * dcache.c: Revert. * darwin-nat.h: Revert. * darwin-nat.c: Revert. * darwin-nat-info.c: Revert. * d-valprint.c: Revert. * d-namespace.c: Revert. * d-lang.c: Revert. * ctf.c: Revert. * csky-tdep.c: Revert. * csky-linux-tdep.c: Revert. * cris-tdep.c: Revert. * cris-linux-tdep.c: Revert. * cp-valprint.c: Revert. * cp-support.c: Revert. * cp-namespace.c: Revert. * cp-abi.c: Revert. * corelow.c: Revert. * corefile.c: Revert. * continuations.c: Revert. * completer.h: Revert. * completer.c: Revert. * complaints.c: Revert. * coffread.c: Revert. * coff-pe-read.c: Revert. * cli-out.h: Revert. * cli-out.c: Revert. * charset.c: Revert. * c-varobj.c: Revert. * c-valprint.c: Revert. * c-typeprint.c: Revert. * c-lang.c: Revert. * buildsym.c: Revert. * buildsym-legacy.c: Revert. * build-id.h: Revert. * build-id.c: Revert. * btrace.c: Revert. * bsd-uthread.c: Revert. * breakpoint.h: Revert. * breakpoint.c: Revert. * break-catch-throw.c: Revert. * break-catch-syscall.c: Revert. * break-catch-sig.c: Revert. * blockframe.c: Revert. * block.c: Revert. * bfin-tdep.c: Revert. * bfin-linux-tdep.c: Revert. * bfd-target.c: Revert. * bcache.c: Revert. * ax-general.c: Revert. * ax-gdb.h: Revert. * ax-gdb.c: Revert. * avr-tdep.c: Revert. * auxv.c: Revert. * auto-load.c: Revert. * arm-wince-tdep.c: Revert. * arm-tdep.c: Revert. * arm-symbian-tdep.c: Revert. * arm-pikeos-tdep.c: Revert. * arm-obsd-tdep.c: Revert. * arm-nbsd-tdep.c: Revert. * arm-nbsd-nat.c: Revert. * arm-linux-tdep.c: Revert. * arm-linux-nat.c: Revert. * arm-fbsd-tdep.c: Revert. * arm-fbsd-nat.c: Revert. * arm-bsd-tdep.c: Revert. * arch-utils.c: Revert. * arc-tdep.c: Revert. * arc-newlib-tdep.c: Revert. * annotate.h: Revert. * annotate.c: Revert. * amd64-windows-tdep.c: Revert. * amd64-windows-nat.c: Revert. * amd64-tdep.c: Revert. * amd64-sol2-tdep.c: Revert. * amd64-obsd-tdep.c: Revert. * amd64-obsd-nat.c: Revert. * amd64-nbsd-tdep.c: Revert. * amd64-nbsd-nat.c: Revert. * amd64-nat.c: Revert. * amd64-linux-tdep.c: Revert. * amd64-linux-nat.c: Revert. * amd64-fbsd-tdep.c: Revert. * amd64-fbsd-nat.c: Revert. * amd64-dicos-tdep.c: Revert. * amd64-darwin-tdep.c: Revert. * amd64-bsd-nat.c: Revert. * alpha-tdep.c: Revert. * alpha-obsd-tdep.c: Revert. * alpha-nbsd-tdep.c: Revert. * alpha-mdebug-tdep.c: Revert. * alpha-linux-tdep.c: Revert. * alpha-linux-nat.c: Revert. * alpha-bsd-tdep.c: Revert. * alpha-bsd-nat.c: Revert. * aix-thread.c: Revert. * agent.c: Revert. * addrmap.c: Revert. * ada-varobj.c: Revert. * ada-valprint.c: Revert. * ada-typeprint.c: Revert. * ada-tasks.c: Revert. * ada-lang.c: Revert. * aarch64-tdep.c: Revert. * aarch64-ravenscar-thread.c: Revert. * aarch64-newlib-tdep.c: Revert. * aarch64-linux-tdep.c: Revert. * aarch64-linux-nat.c: Revert. * aarch64-fbsd-tdep.c: Revert. * aarch64-fbsd-nat.c: Revert. * aarch32-linux-nat.c: Revert.
2019-04-07 03:38:10 +08:00
#include "regcache.h"
#include "user-regs.h"
gdb * varobj.c (value_get_print_value): Include valprint.h. (value_get_print_value): Use get_formatted_print_options. * value.h (struct value_print_options): Declare. (value_print, val_print, common_val_print, val_print_string): Update. * value.c: Include valprint.h. (show_values): Use get_user_print_options. (show_convenience): Likewise. * valprint.h (prettyprint_arrays, prettyprint_structs): Don't declare. (struct value_print_options): New type. (vtblprint, unionprint, addressprint, objectprint, print_max, inspect_it, repeat_count_threshold, output_format, stop_print_at_null): Don't declare. (user_print_options, get_user_print_options, get_raw_print_options, get_formatted_print_options): Declare. (print_array_indexes_p): Don't declare. (maybe_print_array_index, val_print_array_elements): Update. * valprint.c (print_max): Remove. (user_print_options): New global. (get_user_print_options, get_raw_print_options, get_formatted_print_options): New functions. (print_array_indexes, repeat_count_threshold, stop_print_at_null, prettyprint_structs, prettyprint_arrays, unionprint, addressprint): Remove. (val_print): Remove format, deref_ref, pretty arguments; add options. Update. (common_val_print): Likewise. (print_array_indexes_p): Remove. (maybe_print_array_index): Remove format, pretty arguments; add options. Update. (val_print_array_elements): Remove format, deref_ref, pretty arguments; add options. Update. (val_print_string): Add options argument. Update. (_initialize_valprint): Use user_print_options. (output_format): Remove. (set_output_radix_1): Use user_print_options. * typeprint.c: Include valprint.h. (objectprint): Don't declare. (whatis_exp): Use get_user_print_options. * tui/tui-regs.c: Include valprint.h. (tui_register_format): Use get_formatted_print_options. * tracepoint.c: Include valprint.h. (addressprint): Don't declare. (trace_mention): Use get_user_print_options. (tracepoints_info): Likewise. * stack.c (print_frame_args): Use get_raw_print_options. (print_frame_info): Use get_user_print_options. (print_frame): Likewise. * sh64-tdep.c: Include valprint.h (sh64_do_register): Use get_formatted_print_options. * scm-valprint.c (scm_inferior_print): Remove format, deref_ref, pretty arguments; add options. (scm_scmlist_print): Likewise. Update. (scm_scmval_print): Likewise. (scm_val_print): Likewise. (scm_value_print): Remove format, pretty arguments; add options. Update. * scm-lang.h (scm_value_print, scm_val_print, scm_scmval_print): Update. * scm-lang.c (scm_printstr): Add options argument. * python/python-value.c: Include valprint.h. (valpy_str): Use get_user_print_options. * printcmd.c: Include valprint.h. (addressprint): Don't declare. (inspect_it): Remove. (print_formatted): Remove format option; add options. Update. (print_scalar_formatted): Likewise. (print_address_demangle): Use get_user_print_options. (do_examine): Use get_formatted_print_options. (print_command_1): Likewise. (output_command): Use get_formatted_print_options. (do_one_display): Likewise. (print_variable_value): Use get_user_print_options. * p-valprint.c (pascal_val_print): Remove format, deref_ref, pretty arguments; add options. Update. (pascal_value_print): Remove format, pretty arguments; add options. Update. (vtblprint, objectprint): Don't declare. (pascal_static_field_print): Remove. (pascal_object_print_value_fields): Remove format, pretty arguments; add options. Update. (pascal_object_print_static_field): Likewise. (_initialize_pascal_valprint): Use user_print_options. Update. * p-lang.h (pascal_val_print, pascal_value_print, pascal_printstr, pascal_object_print_value_fields): Update. (vtblprint, static_field_print): Don't declare. * p-lang.c (pascal_printstr): Add options argument. Update. * objc-lang.c (objc_printstr): Add options argument. Update. * mt-tdep.c: Include valprint.h. (mt_registers_info): Use get_raw_print_options. * mips-tdep.c: Include valprint.h. (mips_print_fp_register): Use get_formatted_print_options. (mips_print_register): Likewise. * mi/mi-main.c: Include valprint.h. (get_register): Use get_user_print_options. (mi_cmd_data_evaluate_expression): Likewise. (mi_cmd_data_read_memory): Use get_formatted_print_options. * mi/mi-cmd-stack.c: Include valprint.h. (list_args_or_locals): Use get_raw_print_options. * m2-valprint.c (print_function_pointer_address): Add addressprint argument. (m2_print_long_set): Remove format, pretty arguments. (m2_print_unbounded_array): Remove format, deref_ref, pretty arguments; add options. Update. (print_unpacked_pointer): Remove format argument; add options. Now static. Update. (print_variable_at_address): Remove format, deref_ref, pretty arguments; add options. Update. (m2_print_array_contents): Likewise. (m2_val_print): Likewise. * m2-lang.h (m2_val_print): Update. * m2-lang.c (m2_printstr): Add options argument. Update. * language.h (struct value_print_options): Declare. (struct language_defn) <la_printstr>: Add options argument. <la_val_print>: Remove format, deref_ref, pretty argument; add options. <la_value_print>: Remove format, pretty arguments; add options. <la_print_array_index>: Likewise. (LA_VAL_PRINT, LA_VALUE_PRINT, LA_PRINT_STRING, LA_PRINT_ARRAY_INDEX): Update. (default_print_array_index): Update. * language.c (default_print_array_index): Remove format, pretty arguments; add options. Update. (unk_lang_printstr): Add options argument. (unk_lang_val_print): Remove format, deref_ref, pretty arguments; add options. (unk_lang_value_print): Remove format, pretty arguments; add options. * jv-valprint.c (java_value_print): Remove format, pretty arguments; add options. Update. (java_print_value_fields): Likewise. (java_val_print): Remove format, deref_ref, pretty arguments; add options. Update. * jv-lang.h (java_val_print, java_value_print): Declare. * infcmd.c: Include valprint.h. (print_return_value): Use get_raw_print_options. (default_print_registers_info): Use get_user_print_options, get_formatted_print_options. (registers_info): Use get_formatted_print_options. * gdbtypes.h (struct value_print_options): Declare. (print_scalar_formatted): Update. * f-valprint.c (f77_print_array_1): Remove format, deref_ref, pretty arguments; add options. Update. (f77_print_array): Likewise. (f_val_print): Likewise. * f-lang.h (f_val_print): Update. * f-lang.c (f_printstr): Add options argument. Update. (c_value_print): Update declaration. * expprint.c: Include valprint.h. (print_subexp_standard): Use get_raw_print_options, get_user_print_options. * eval.c: Include valprint.h. (objectprint): Don't declare. (evaluate_subexp_standard): Use get_user_print_options. * cp-valprint.c (vtblprint, objectprint, static_field_print): Remove. (cp_print_value_fields): Remove format, pretty arguments; add options. Update. (cp_print_value): Likewise. (cp_print_static_field): Likewise. (_initialize_cp_valprint): Use user_print_options. Update. * c-valprint.c (print_function_pointer_address): Add addressprint argument. (c_val_print): Remove format, deref_ref, pretty arguments; add options. Update. (c_value_print): Add options argument. Update. * c-lang.h (c_val_print, c_value_print, c_printstr): Update. (vtblprint, static_field_print): Don't declare. (cp_print_value_fields): Update. * c-lang.c (c_printstr): Add options argument. Update. * breakpoint.c: Include valprint.h. (addressprint): Don't declare. (watchpoint_value_print): Use get_user_print_options. (print_one_breakpoint_location): Likewise. (breakpoint_1, print_it_catch_fork, print_it_catch_vfork, mention, print_exception_catchpoint): Likewise. * auxv.c (fprint_target_auxv): Don't declare addressprint. Use get_user_print_options. * ada-valprint.c (struct ada_val_print_args): Remove format, deref_ref, and pretty; add options. (print_optional_low_bound): Add options argument. (val_print_packed_array_elements): Remove format and pretty arguments; add options. Update. (printstr): Add options argument. Update. (ada_printstr): Likewise. (ada_val_print): Remove format, deref_ref, pretty arguments; add options argument. Update. (ada_val_print_stub): Update. (ada_val_print_array): Remove format, deref_ref, pretty arguments; add options. Update. (ada_val_print_1): Likewise. (print_variant_part): Likewise. (ada_value_print): Remove format, pretty arguments; add options. Update. (print_record): Likewise. (print_field_values): Likewise. * ada-lang.h (ada_val_print, ada_value_print, ada_printstr): Update. * ada-lang.c (ada_print_array_index): Add options argument; remove format and pretty arguments. (print_one_exception): Use get_user_print_options. gdb/testsuite * gdb.base/exprs.exp (test_expr): Add enum formatting tests.
2008-10-29 01:19:58 +08:00
#include "valprint.h"
#include "gdbsupport/gdb_obstack.h"
Revert the header-sorting patch Andreas Schwab and John Baldwin pointed out some bugs in the header sorting patch; and I noticed that the output was not correct when limited to a subset of files (a bug in my script). So, I'm reverting the patch. I may try again after fixing the issues pointed out. gdb/ChangeLog 2019-04-05 Tom Tromey <tom@tromey.com> Revert the header-sorting patch. * ft32-tdep.c: Revert. * frv-tdep.c: Revert. * frv-linux-tdep.c: Revert. * frame.c: Revert. * frame-unwind.c: Revert. * frame-base.c: Revert. * fork-child.c: Revert. * findvar.c: Revert. * findcmd.c: Revert. * filesystem.c: Revert. * filename-seen-cache.h: Revert. * filename-seen-cache.c: Revert. * fbsd-tdep.c: Revert. * fbsd-nat.h: Revert. * fbsd-nat.c: Revert. * f-valprint.c: Revert. * f-typeprint.c: Revert. * f-lang.c: Revert. * extension.h: Revert. * extension.c: Revert. * extension-priv.h: Revert. * expprint.c: Revert. * exec.h: Revert. * exec.c: Revert. * exceptions.c: Revert. * event-top.c: Revert. * event-loop.c: Revert. * eval.c: Revert. * elfread.c: Revert. * dwarf2read.h: Revert. * dwarf2read.c: Revert. * dwarf2loc.c: Revert. * dwarf2expr.h: Revert. * dwarf2expr.c: Revert. * dwarf2-frame.c: Revert. * dwarf2-frame-tailcall.c: Revert. * dwarf-index-write.h: Revert. * dwarf-index-write.c: Revert. * dwarf-index-common.c: Revert. * dwarf-index-cache.h: Revert. * dwarf-index-cache.c: Revert. * dummy-frame.c: Revert. * dtrace-probe.c: Revert. * disasm.h: Revert. * disasm.c: Revert. * disasm-selftests.c: Revert. * dictionary.c: Revert. * dicos-tdep.c: Revert. * demangle.c: Revert. * dcache.h: Revert. * dcache.c: Revert. * darwin-nat.h: Revert. * darwin-nat.c: Revert. * darwin-nat-info.c: Revert. * d-valprint.c: Revert. * d-namespace.c: Revert. * d-lang.c: Revert. * ctf.c: Revert. * csky-tdep.c: Revert. * csky-linux-tdep.c: Revert. * cris-tdep.c: Revert. * cris-linux-tdep.c: Revert. * cp-valprint.c: Revert. * cp-support.c: Revert. * cp-namespace.c: Revert. * cp-abi.c: Revert. * corelow.c: Revert. * corefile.c: Revert. * continuations.c: Revert. * completer.h: Revert. * completer.c: Revert. * complaints.c: Revert. * coffread.c: Revert. * coff-pe-read.c: Revert. * cli-out.h: Revert. * cli-out.c: Revert. * charset.c: Revert. * c-varobj.c: Revert. * c-valprint.c: Revert. * c-typeprint.c: Revert. * c-lang.c: Revert. * buildsym.c: Revert. * buildsym-legacy.c: Revert. * build-id.h: Revert. * build-id.c: Revert. * btrace.c: Revert. * bsd-uthread.c: Revert. * breakpoint.h: Revert. * breakpoint.c: Revert. * break-catch-throw.c: Revert. * break-catch-syscall.c: Revert. * break-catch-sig.c: Revert. * blockframe.c: Revert. * block.c: Revert. * bfin-tdep.c: Revert. * bfin-linux-tdep.c: Revert. * bfd-target.c: Revert. * bcache.c: Revert. * ax-general.c: Revert. * ax-gdb.h: Revert. * ax-gdb.c: Revert. * avr-tdep.c: Revert. * auxv.c: Revert. * auto-load.c: Revert. * arm-wince-tdep.c: Revert. * arm-tdep.c: Revert. * arm-symbian-tdep.c: Revert. * arm-pikeos-tdep.c: Revert. * arm-obsd-tdep.c: Revert. * arm-nbsd-tdep.c: Revert. * arm-nbsd-nat.c: Revert. * arm-linux-tdep.c: Revert. * arm-linux-nat.c: Revert. * arm-fbsd-tdep.c: Revert. * arm-fbsd-nat.c: Revert. * arm-bsd-tdep.c: Revert. * arch-utils.c: Revert. * arc-tdep.c: Revert. * arc-newlib-tdep.c: Revert. * annotate.h: Revert. * annotate.c: Revert. * amd64-windows-tdep.c: Revert. * amd64-windows-nat.c: Revert. * amd64-tdep.c: Revert. * amd64-sol2-tdep.c: Revert. * amd64-obsd-tdep.c: Revert. * amd64-obsd-nat.c: Revert. * amd64-nbsd-tdep.c: Revert. * amd64-nbsd-nat.c: Revert. * amd64-nat.c: Revert. * amd64-linux-tdep.c: Revert. * amd64-linux-nat.c: Revert. * amd64-fbsd-tdep.c: Revert. * amd64-fbsd-nat.c: Revert. * amd64-dicos-tdep.c: Revert. * amd64-darwin-tdep.c: Revert. * amd64-bsd-nat.c: Revert. * alpha-tdep.c: Revert. * alpha-obsd-tdep.c: Revert. * alpha-nbsd-tdep.c: Revert. * alpha-mdebug-tdep.c: Revert. * alpha-linux-tdep.c: Revert. * alpha-linux-nat.c: Revert. * alpha-bsd-tdep.c: Revert. * alpha-bsd-nat.c: Revert. * aix-thread.c: Revert. * agent.c: Revert. * addrmap.c: Revert. * ada-varobj.c: Revert. * ada-valprint.c: Revert. * ada-typeprint.c: Revert. * ada-tasks.c: Revert. * ada-lang.c: Revert. * aarch64-tdep.c: Revert. * aarch64-ravenscar-thread.c: Revert. * aarch64-newlib-tdep.c: Revert. * aarch64-linux-tdep.c: Revert. * aarch64-linux-nat.c: Revert. * aarch64-fbsd-tdep.c: Revert. * aarch64-fbsd-nat.c: Revert. * aarch32-linux-nat.c: Revert.
2019-04-07 03:38:10 +08:00
#include "objfiles.h"
#include "typeprint.h"
#include <ctype.h>
Introduce class operation This patch introduces class operation, the new base class for all expression operations. In the new approach, an operation is simply a class that presents a certain interface. Operations own their operands, and management is done via unique_ptr. The operation interface is largely ad hoc, based on the evolution of expression handling in GDB. Parts (for example, evaluate_with_coercion) are probably redundant; however I took this approach to try to avoid mixing different kinds of refactorings. In some specific situations, rather than add a generic method across the entire operation class hierarchy, I chose instead to use dynamic_cast and specialized methods on certain concrete subclasses. This will appear in some subsequent patches. One goal of this work is to avoid the kinds of easy-to-make errors that affected the old implementation. To this end, some helper subclasses are also added here. These helpers automate the implementation of the 'dump', 'uses_objfile', and 'constant_p' methods. Nearly every concrete operation that is subsequently added will use these facilities. (Note that the 'dump' implementation is only outlined here, the body appears in the next patch.) gdb/ChangeLog 2021-03-08 Tom Tromey <tom@tromey.com> * expression.h (expr::operation): New class. (expr::make_operation): New function. (expr::operation_up): New typedef. * expop.h: New file. * eval.c (operation::evaluate_for_cast) (operation::evaluate_for_address, operation::evaluate_for_sizeof): New methods. * ax-gdb.c (operation::generate_ax): New method.
2021-03-08 22:27:57 +08:00
#include "expop.h"
#include "c-exp.h"
#include "inferior.h"
gdb/ 2009-03-05 Tom Tromey <tromey@redhat.com> Add support for convenience functions in Python. * Makefile.in (SUBDIR_PYTHON_OBS): Add python-function.o. (SUBDIR_PYTHON_SRCS): Add python-function.c. (python-function.o): New target. * eval.c: Include "python/python.h" and <ctype.h>. (evaluate_subexp_standard): Handle values of type TYPE_CODE_INTERNAL_FUNCTION. * gdbtypes.h (type_code): Add TYPE_CODE_INTERNAL_FUNCTION. * parse.c (write_exp_string): Remove duplicate word in comment. * python/python-function.c: New file. * python/python-internal.h (gdbpy_initialize_functions): Add prototype. * python/python.c (_initialize_python): Call gdbpy_initialize_functions. * valprint.c (value_check_printable): Handle values of type TYPE_CODE_INTERNAL_FUNCTION. * value.c: Include "cli/cli-decode.h". (internal_function): New struct. (functionlist, internal_fn_type): New static variables. (lookup_only_internalvar, lookup_internalvar): Add const qualifier to name argument. (create_internalvar): Likewise. Initialize new field. (set_internal_var): Fix typo in comment. Don't allow assignment to canonical variable. (value_create_internal_function, value_internal_function_name, call_internal_function, function_command, function_destroyer, add_internal_function): New functions. (_initialize_values): Create `function' placeholder command. Initialize internal_fn_type. * value.h (lookup_only_internalvar, create_internalvar, lookup_internalvar): Add const qualifier to name argument. (internal_function_fn, add_internal_function, call_internal_function, value_internal_function_name): Add prototypes. (struct internalvar) <canonical>: New field. gdb/doc/ 2008-03-05 Tom Tromey <tromey@redhat.com> * gdb.texinfo (Convenience Vars): Document convenience functions. (Functions In Python): New node. (Python API): Update. gdb/testsuite/ 2009-03-05 Thiago Jung Bauermann <bauerman@br.ibm.com> * gdb.python/python-function.exp: New file.
2009-03-21 11:03:56 +08:00
/* Parse the string EXP as a C expression, evaluate it,
and return the result as a number. */
CORE_ADDR
* ada-lang.c (ada_read_renaming_var_value): Pass const pointer to expression string to parse_exp_1. (create_excep_cond_exprs): Likewise. * ax-gdb.c (agent_eval_command_one): Likewise. (maint_agent_printf_command): Likewise. Constify much of the string handling/parsing. * breakpoint.c (set_breakpoint_condition): Pass const pointer to expression string to parse_exp_1. (update_watchpoint): Likewise. (parse_cmd_to_aexpr): Constify string handling. Pass const pointer to parse_exp_1. (init_breakpoint_sal): Pass const pointer to parse_exp_1. (find_condition_and_thread): Likewise. Make TOK const. (watch_command_1): Make "arg" const. Constify string handling. Copy the expression string instead of changing the input string. (update_breakpoint_location): Pass const pointer to parse_exp_1. * eval.c (parse_and_eval_address): Make "exp" const. (parse_to_comma_and_eval): Make "expp" const. (parse_and_eval): Make "exp" const. * expression.h (parse_expression): Make argument const. (parse_exp_1): Make first argument const. * findcmd.c (parse_find_args): Treat "args" as const. * linespec.c (parse_linespec): Pass const pointer to linespec_expression_to_pc. (linespec_expression_to_pc): Make "exp_ptr" const. * parse.c (parse_exp_1): Make "stringptr" const. Make a copy of the expression to pass to parse_exp_in_context until this whole interface can be constified. (parse_expression): Make "string" const. * printcmd.c (ui_printf): Treat "arg" as const. Handle const strings. * tracepoint.c (validate_actionline): Pass const pointer to all calls to parse_exp_1. (encode_actions_1): Likewise. * value.h (parse_to_comma_and_eval): Make argument const. (parse_and_eval_address): Likewise. (parse_and_eval): Likewise. * varobj.c (varobj_create): Pass const pointer to parse_exp_1. (varobj_set_value): Likewise. * cli/cli-cmds.c (disassemble_command): Treat "arg" as const and constify string handling. Pass const pointers to parse_and_eval_address and parse_to_comman_and_eval. * cli/cli-utils.c (skip_to_space): Rename to ... (skip_to_space_const): ... this. Handle const strings. * cli/cli-utils.h (skip_to_space): Turn into macro which invokes skip_to_space_const. (skip_to_space_const): Declare. * common/format.c (parse_format_string): Make "arg" const. Handle const strings. * common/format.h (parse_format_string): Make "arg" const. * gdbserver/ax.c (ax_printf): Make "format" const. * python/python.c (gdbpy_parse_and_eval): Do not make a copy of the expression string.
2013-03-13 01:39:45 +08:00
parse_and_eval_address (const char *exp)
{
'struct expression *' -> gdb::unique_xmalloc_ptr<expression> This patch makes parse_expression and friends return a unique_ptr instead of raw pointer [1]: typedef gdb::unique_malloc_ptr<expression> expression_up; and then adjusts the codebase throughout to stop using cleanups to manage lifetime of expression pointers. Whenever I found a structure owning an expression pointer, I made it store a unique_ptr instead of a raw pointer, which then requires using new/delete of the holding structure, instead of XNEW/xfree. [1] - I'd like to set the rule that types named with an "_up" suffix are unique_ptr typedefs. Note I used gdb::unique_xmalloc_ptr instead of gdb::unique_ptr, simply because we still use xmalloc instead of new to allocate expression objects. Once that's changed, all we need to do is change the expression_up typedef and the smart pointer will then call delete instead of xfree. gdb/ChangeLog: 2016-11-08 Pedro Alves <palves@redhat.com> * ada-lang.c (ada_read_renaming_var_value): Use expression_up. (struct ada_catchpoint_location) <excep_cond_expr>: Now an expression_up. (ada_catchpoint_location_dtor): Reset excep_cond_expr instead of using xfree. (create_excep_cond_exprs): Use expression_up and gdb::move. (allocate_location_exception): Use new instead of XNEW. (should_stop_exception): Likewise. Adjust to use expression_up. (create_ada_exception_catchpoint): Use new instead of XNEW. * ax-gdb.c (agent_eval_command_one): Use expression_up instead of cleanups. (maint_agent_printf_command): Use expression_up. * break-catch-sig.c (create_signal_catchpoint): Use new instead of XNEW. * break-catch-syscall.c (create_syscall_event_catchpoint): Likewise. * break-catch-throw.c (handle_gnu_v3_exceptions): Use new instead of XCNEW. Use gdb::unique_ptr instead of cleanups. * breakpoint.c (set_breakpoint_condition, update_watchpoint) (parse_cmd_to_aexpr, watchpoint_check) (bpstat_check_breakpoint_conditions, watchpoint_locations_match): Adjust to use expression_up. (init_bp_location): Adjust. (free_bp_location): Use delete instead of xfree. (set_raw_breakpoint_without_location, set_raw_breakpoint) (add_solib_catchpoint, create_fork_vfork_event_catchpoint) (new_single_step_breakpoint, create_breakpoint_sal): Use new instead of XNEW. (find_condition_and_thread): Adjust to use expression_up. (create_breakpoint): Use new instead of XNEW. (dtor_watchpoint): Don't xfree expression pointers, they're unique_ptr's now. (insert_watchpoint, remove_watchpoint): Adjust. (watch_command_1): Use expression_up. Use new instead of XCNEW. (catch_exec_command_1): Use new instead of XNEW. (bp_location_dtor): Don't xfree expression pointers, they're unique_ptr's now. (base_breakpoint_allocate_location) (strace_marker_create_breakpoints_sal): Use new instead of XNEW. (delete_breakpoint): Use delete instead of xfree. * breakpoint.h (struct bp_location) <cond>: Now an unique_ptr<expression> instead of a raw pointer. (struct watchpoint) <exp, cond_exp>: Likewise. * cli/cli-script.c (execute_control_command): Use expression_up instead of cleanups. * dtrace-probe.c (dtrace_process_dof_probe): Use expression_up. * eval.c (parse_and_eval_address, parse_and_eval_long) (parse_and_eval, parse_to_comma_and_eval, parse_and_eval_type): Use expression_up instead of cleanups. * expression.h (expression_up): New typedef. (parse_expression, parse_expression_with_language, parse_exp_1): Change return type to expression_up. * mi/mi-main.c (mi_cmd_data_evaluate_expression) (print_variable_or_computed): Use expression_up. * objc-lang.c (print_object_command): Use expression_up instead of cleanups. * parse.c (parse_exp_1, parse_exp_in_context) (parse_exp_in_context_1, parse_expression) (parse_expression_with_language): Return an expression_up instead of a raw pointer. (parse_expression_for_completion): Use expression_up. * printcmd.c (struct display) <exp>: Now an expression_up instead of a raw pointer. (print_command_1, output_command_const, set_command, x_command): Use expression_up instead of cleanups. (display_command): Likewise. Use new instead of XNEW. (free_display): Use delete instead of xfree. (do_one_display): Adjust to use expression_up. * remote.c (remote_download_tracepoint): Likewise. * stack.c (return_command): Likewise. * tracepoint.c (validate_actionline, encode_actions_1): Use expression_up instead of cleanups. * typeprint.c (whatis_exp, maintenance_print_type): Likewise. * value.c (init_if_undefined_command): Likewise. * varobj.c (struct varobj_root) <exp>: Now an expression_up instead of a raw pointer. (varobj_create): Adjust. (varobj_set_value): Use an expression_up instead of cleanups. (new_root_variable): Use new instead of XNEW. (free_variable): Use delete instead of xfree. (value_of_root_1): Use std::swap.
2016-11-08 23:26:43 +08:00
expression_up expr = parse_expression (exp);
return value_as_address (expr->evaluate ());
}
/* Like parse_and_eval_address, but treats the value of the expression
2011-01-07 Michael Snyder <msnyder@vmware.com> * ada-lang.c: Comment cleanup, mostly periods and spaces. * ada-lang.h: Ditto. * ada-tasks.c: Ditto. * ada-valprint.c: Ditto. * aix-threads.c: Ditto. * alpha-linux-nat.c: Ditto. * alpha-linux-tdep.c: Ditto. * alpha-mdebug-tdep.c: Ditto. * alpha-nat.c: Ditto. * alpha-osf1-tdep.c: Ditto. * alpha-tdep.c: Ditto. * alphabsd-nat.c: Ditto. * alphabsd-tdep.c: Ditto. * amd64-darwin-tdep.c: Ditto. * amd64-linux-nat.c: Ditto. * amd64-linux-tdep.c: Ditto. * amd64-sol2-tdep.c: Ditto. * amd64-tdep.c: Ditto. * amd64-fbsd-tdep.c: Ditto. * amd64-nbsd-tdep.c: Ditto. * amd64-obsd-tdep.c: Ditto. * amd64-linux-nat.c: Ditto. * amd64-linux-tdep.c: Ditto. * arm-tdep.c: Ditto. * arm-tdep.h: Ditto. * armnbsd-nat.c: Ditto. * avr-tdep.c: Ditto. * bfin-tdep.c: Ditto. * bsd-kvm.c: Ditto. * c-typeprintc: Ditto. * c-valprint.c: Ditto. * coff-pe-read.h: Ditto. * coffreead.c: Ditto. * cris-tdep.c: Ditto. * d-lang.c: Ditto. * darwin-nat-info.c: Ditto. * darwin-nat.c: Ditto. * dbug-rom.c: Ditto. * dbxread.c: Ditto. * dcache.c: Ditto. * dcache.h: Ditto. * dec-thread.c: Ditto. * defs.h: Ditto. * demangle.c: Ditto. * dicos-tdep.c: Ditto. * dictionary.c: Ditto. * dictionary.h: Ditto. * dink32-rom.c: Ditto. * disasm.c: Ditto. * doublest.c: Ditto. * dsrec.c: Ditto. * dummy-frame.c: Ditto. * dwarf2-frame.c: Ditto. * dwarf2expr.c: Ditto. * dwarf2loc.c: Ditto. * dwarf2read.c: Ditto. * elfread.c: Ditto. * environ.c: Ditto. * eval.c: Ditto. * event-top.h: Ditto. * exceptions.c: Ditto. * exceptions.h: Ditto. * exec.c: Ditto. * expprint.c: Ditto. * expression.h: Ditto. * f-exp.y: Ditto. * f-lang.c: Ditto. * f-lang.h: Ditto. * f-typeprint.c: Ditto. * f-valprint.c: Ditto. * fbsd-nat.c: Ditto. * findvar.c: Ditto. * fork-child.c: Ditto. * frame.c: Ditto. * frame.h: Ditto. * frv-linux-tdep.c: Ditto. * frv-tdep.c: Ditto. * gcore.c: Ditto. * gdb-stabs.h: Ditto. * gdb_assert.h: Ditto. * gdb_string.h: Ditto. * gdb_thread_db.h: Ditto. * gdb_wait.h: Ditto. * gdbarch.sh: Ditto. * gdbcore.h: Ditto. * gdbthread.h: Ditto. * gdbtypes.c: Ditto. * gdbtypes.h: Ditto. * gnu-nat.c: Ditto. * gnu-nat.h: Ditto. * gnu-v2-abi.c: Ditto. * gnu-v3-abi.c: Ditto. * go32-nat.c: Ditto. * gdbarch.c: Regenerate. * gdbarch.h: Regenerate.
2011-01-08 03:36:19 +08:00
as an integer, not an address, returns a LONGEST, not a CORE_ADDR. */
LONGEST
parse_and_eval_long (const char *exp)
{
'struct expression *' -> gdb::unique_xmalloc_ptr<expression> This patch makes parse_expression and friends return a unique_ptr instead of raw pointer [1]: typedef gdb::unique_malloc_ptr<expression> expression_up; and then adjusts the codebase throughout to stop using cleanups to manage lifetime of expression pointers. Whenever I found a structure owning an expression pointer, I made it store a unique_ptr instead of a raw pointer, which then requires using new/delete of the holding structure, instead of XNEW/xfree. [1] - I'd like to set the rule that types named with an "_up" suffix are unique_ptr typedefs. Note I used gdb::unique_xmalloc_ptr instead of gdb::unique_ptr, simply because we still use xmalloc instead of new to allocate expression objects. Once that's changed, all we need to do is change the expression_up typedef and the smart pointer will then call delete instead of xfree. gdb/ChangeLog: 2016-11-08 Pedro Alves <palves@redhat.com> * ada-lang.c (ada_read_renaming_var_value): Use expression_up. (struct ada_catchpoint_location) <excep_cond_expr>: Now an expression_up. (ada_catchpoint_location_dtor): Reset excep_cond_expr instead of using xfree. (create_excep_cond_exprs): Use expression_up and gdb::move. (allocate_location_exception): Use new instead of XNEW. (should_stop_exception): Likewise. Adjust to use expression_up. (create_ada_exception_catchpoint): Use new instead of XNEW. * ax-gdb.c (agent_eval_command_one): Use expression_up instead of cleanups. (maint_agent_printf_command): Use expression_up. * break-catch-sig.c (create_signal_catchpoint): Use new instead of XNEW. * break-catch-syscall.c (create_syscall_event_catchpoint): Likewise. * break-catch-throw.c (handle_gnu_v3_exceptions): Use new instead of XCNEW. Use gdb::unique_ptr instead of cleanups. * breakpoint.c (set_breakpoint_condition, update_watchpoint) (parse_cmd_to_aexpr, watchpoint_check) (bpstat_check_breakpoint_conditions, watchpoint_locations_match): Adjust to use expression_up. (init_bp_location): Adjust. (free_bp_location): Use delete instead of xfree. (set_raw_breakpoint_without_location, set_raw_breakpoint) (add_solib_catchpoint, create_fork_vfork_event_catchpoint) (new_single_step_breakpoint, create_breakpoint_sal): Use new instead of XNEW. (find_condition_and_thread): Adjust to use expression_up. (create_breakpoint): Use new instead of XNEW. (dtor_watchpoint): Don't xfree expression pointers, they're unique_ptr's now. (insert_watchpoint, remove_watchpoint): Adjust. (watch_command_1): Use expression_up. Use new instead of XCNEW. (catch_exec_command_1): Use new instead of XNEW. (bp_location_dtor): Don't xfree expression pointers, they're unique_ptr's now. (base_breakpoint_allocate_location) (strace_marker_create_breakpoints_sal): Use new instead of XNEW. (delete_breakpoint): Use delete instead of xfree. * breakpoint.h (struct bp_location) <cond>: Now an unique_ptr<expression> instead of a raw pointer. (struct watchpoint) <exp, cond_exp>: Likewise. * cli/cli-script.c (execute_control_command): Use expression_up instead of cleanups. * dtrace-probe.c (dtrace_process_dof_probe): Use expression_up. * eval.c (parse_and_eval_address, parse_and_eval_long) (parse_and_eval, parse_to_comma_and_eval, parse_and_eval_type): Use expression_up instead of cleanups. * expression.h (expression_up): New typedef. (parse_expression, parse_expression_with_language, parse_exp_1): Change return type to expression_up. * mi/mi-main.c (mi_cmd_data_evaluate_expression) (print_variable_or_computed): Use expression_up. * objc-lang.c (print_object_command): Use expression_up instead of cleanups. * parse.c (parse_exp_1, parse_exp_in_context) (parse_exp_in_context_1, parse_expression) (parse_expression_with_language): Return an expression_up instead of a raw pointer. (parse_expression_for_completion): Use expression_up. * printcmd.c (struct display) <exp>: Now an expression_up instead of a raw pointer. (print_command_1, output_command_const, set_command, x_command): Use expression_up instead of cleanups. (display_command): Likewise. Use new instead of XNEW. (free_display): Use delete instead of xfree. (do_one_display): Adjust to use expression_up. * remote.c (remote_download_tracepoint): Likewise. * stack.c (return_command): Likewise. * tracepoint.c (validate_actionline, encode_actions_1): Use expression_up instead of cleanups. * typeprint.c (whatis_exp, maintenance_print_type): Likewise. * value.c (init_if_undefined_command): Likewise. * varobj.c (struct varobj_root) <exp>: Now an expression_up instead of a raw pointer. (varobj_create): Adjust. (varobj_set_value): Use an expression_up instead of cleanups. (new_root_variable): Use new instead of XNEW. (free_variable): Use delete instead of xfree. (value_of_root_1): Use std::swap.
2016-11-08 23:26:43 +08:00
expression_up expr = parse_expression (exp);
return value_as_long (expr->evaluate ());
}
2001-11-11 04:15:13 +08:00
struct value *
parse_and_eval (const char *exp, parser_flags flags)
{
expression_up expr = parse_expression (exp, nullptr, flags);
return expr->evaluate ();
}
/* Parse up to a comma (or to a closeparen)
in the string EXPP as an expression, evaluate it, and return the value.
EXPP is advanced to point to the comma. */
2001-11-11 04:15:13 +08:00
struct value *
* ada-lang.c (ada_read_renaming_var_value): Pass const pointer to expression string to parse_exp_1. (create_excep_cond_exprs): Likewise. * ax-gdb.c (agent_eval_command_one): Likewise. (maint_agent_printf_command): Likewise. Constify much of the string handling/parsing. * breakpoint.c (set_breakpoint_condition): Pass const pointer to expression string to parse_exp_1. (update_watchpoint): Likewise. (parse_cmd_to_aexpr): Constify string handling. Pass const pointer to parse_exp_1. (init_breakpoint_sal): Pass const pointer to parse_exp_1. (find_condition_and_thread): Likewise. Make TOK const. (watch_command_1): Make "arg" const. Constify string handling. Copy the expression string instead of changing the input string. (update_breakpoint_location): Pass const pointer to parse_exp_1. * eval.c (parse_and_eval_address): Make "exp" const. (parse_to_comma_and_eval): Make "expp" const. (parse_and_eval): Make "exp" const. * expression.h (parse_expression): Make argument const. (parse_exp_1): Make first argument const. * findcmd.c (parse_find_args): Treat "args" as const. * linespec.c (parse_linespec): Pass const pointer to linespec_expression_to_pc. (linespec_expression_to_pc): Make "exp_ptr" const. * parse.c (parse_exp_1): Make "stringptr" const. Make a copy of the expression to pass to parse_exp_in_context until this whole interface can be constified. (parse_expression): Make "string" const. * printcmd.c (ui_printf): Treat "arg" as const. Handle const strings. * tracepoint.c (validate_actionline): Pass const pointer to all calls to parse_exp_1. (encode_actions_1): Likewise. * value.h (parse_to_comma_and_eval): Make argument const. (parse_and_eval_address): Likewise. (parse_and_eval): Likewise. * varobj.c (varobj_create): Pass const pointer to parse_exp_1. (varobj_set_value): Likewise. * cli/cli-cmds.c (disassemble_command): Treat "arg" as const and constify string handling. Pass const pointers to parse_and_eval_address and parse_to_comman_and_eval. * cli/cli-utils.c (skip_to_space): Rename to ... (skip_to_space_const): ... this. Handle const strings. * cli/cli-utils.h (skip_to_space): Turn into macro which invokes skip_to_space_const. (skip_to_space_const): Declare. * common/format.c (parse_format_string): Make "arg" const. Handle const strings. * common/format.h (parse_format_string): Make "arg" const. * gdbserver/ax.c (ax_printf): Make "format" const. * python/python.c (gdbpy_parse_and_eval): Do not make a copy of the expression string.
2013-03-13 01:39:45 +08:00
parse_to_comma_and_eval (const char **expp)
{
expression_up expr = parse_exp_1 (expp, 0, nullptr,
PARSER_COMMA_TERMINATES);
return expr->evaluate ();
}
/* See expression.h. */
bool
expression::uses_objfile (struct objfile *objfile) const
{
gdb_assert (objfile->separate_debug_objfile_backlink == nullptr);
return op->uses_objfile (objfile);
}
/* See expression.h. */
struct value *
expression::evaluate (struct type *expect_type, enum noside noside)
{
std::optional<enable_thread_stack_temporaries> stack_temporaries;
gdb: fix eval.c assert during inferior exit event Evaluating expressions from within an inferior exit event handler can cause a crash: echo "int main() { return 0; }" > repro.c gcc -g repro.c -o repro ./gdb -q --ex "set language c++" --ex "python gdb.events.exited.connect(lambda _: gdb.execute('set \$_a=0'))" --ex "run" repro Reading symbols from repro... Starting program: /home/mhov/repos/binutils-gdb-master/install-bad/bin/repro [Inferior 1 (process 1974779) exited normally] ../../gdb/thread.c:72: internal-error: thread_info* inferior_thread(): Assertion `current_thread_ != nullptr' failed. A problem internal to GDB has been detected, further debugging may prove unreliable. Quit this debugging session? (y or n) [answered Y; input not from terminal] This is a bug, please report it. For instructions, see: <https://www.gnu.org/software/gdb/bugs/>. Backtrace 0 in internal_error of ../../gdbsupport/errors.cc:51 1 in inferior_thread of ../../gdb/thread.c:72 2 in expression::evaluate of ../../gdb/eval.c:98 3 in evaluate_expression of ../../gdb/eval.c:115 4 in set_command of ../../gdb/printcmd.c:1502 5 in do_const_cfunc of ../../gdb/cli/cli-decode.c:101 6 in cmd_func of ../../gdb/cli/cli-decode.c:2181 7 in execute_command of ../../gdb/top.c:670 ... 22 in python_inferior_exit of ../../gdb/python/py-inferior.c:182 In `expression::evaluate (...)' there is a call to `inferior_thread ()' that is guarded by `target_has_execution ()': struct value * expression::evaluate (struct type *expect_type, enum noside noside) { gdb::optional<enable_thread_stack_temporaries> stack_temporaries; if (target_has_execution () && language_defn->la_language == language_cplus && !thread_stack_temporaries_enabled_p (inferior_thread ())) stack_temporaries.emplace (inferior_thread ()); The `target_has_execution ()' guard maps onto `inf->pid' and the `inferior_thread ()' call assumes that `current_thread_' is set to something meaningful: struct thread_info* inferior_thread (void) { gdb_assert (current_thread_ != nullptr); return current_thread_; } In other words, it is assumed that if `inf->pid' is set then `current_thread_' must also be set. This does not hold at the point where inferior exit observers are notified: - `generic_mourn_inferior (...)' - `switch_to_no_thread ()' - `current_thread_ = nullptr;' - `exit_inferior (...)' - `gdb::observers::inferior_exit.notify (...)' - `inf->pid = 0' The inferior exit notification means that a Python handler can get a chance to run while `current_thread' has been cleared and the `inf->pid' has not been cleared. Since the Python handler can call any GDB command with `gdb.execute(...)' (in my case `gdb.execute("set $_a=0")' we can end up evaluating expressions and asserting in `evaluate_subexp (...)'. This patch adds a test in `evaluate_subexp (...)' to check the global `inferior_ptid' which is reset at the same time as `current_thread_'. Checking `inferior_ptid' at the same time as `target_has_execution ()' seems to be a common pattern: $ git grep -n -e inferior_ptid --and -e target_has_execution gdb/breakpoint.c:2998: && (inferior_ptid == null_ptid || !target_has_execution ())) gdb/breakpoint.c:3054: && (inferior_ptid == null_ptid || !target_has_execution ())) gdb/breakpoint.c:4587: if (inferior_ptid == null_ptid || !target_has_execution ()) gdb/infcmd.c:360: if (inferior_ptid != null_ptid && target_has_execution ()) gdb/infcmd.c:2380: /* FIXME: This should not really be inferior_ptid (or target_has_execution). gdb/infrun.c:3438: if (!target_has_execution () || inferior_ptid == null_ptid) gdb/remote.c:11961: if (!target_has_execution () || inferior_ptid == null_ptid) gdb/solib.c:725: if (target_has_execution () && inferior_ptid != null_ptid) The testsuite has been run on 5.4.0-59-generic x86_64 GNU/Linux: - Ubuntu 20.04.1 LTS - gcc (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0 - DejaGnu version 1.6.2 - Expect version 5.45.4 - Tcl version 8.6 - Native configuration: x86_64-pc-linux-gnu - Target: unix Results show a few XFAIL in gdb.threads/attach-many-short-lived-threads.exp. The existing py-events.exp tests are skipped for native-gdbserver and fail for native-extended-gdbserver, but the new tests pass with native-extended-gdbserver when run without the existing tests. gdb/ChangeLog: 2021-06-03 Magne Hov <mhov@undo.io> PR python/27841 * eval.c (expression::evaluate): Check inferior_ptid. gdb/testsuite/ChangeLog: 2021-06-03 Magne Hov <mhov@undo.io> PR python/27841 * gdb.python/py-events.exp: Extend inferior exit tests. * gdb.python/py-events.py: Print inferior exit PID.
2021-06-04 04:20:30 +08:00
if (target_has_execution () && inferior_ptid != null_ptid
&& language_defn->la_language == language_cplus
&& !thread_stack_temporaries_enabled_p (inferior_thread ()))
stack_temporaries.emplace (inferior_thread ());
Remove union exp_element This removes union exp_element functions that either create such elements or walk them. struct expression no longer holds exp_elements. A couple of language_defn methods are also removed, as they are obsolete. Note that this patch also removes the print_expression code. The only in-tree caller of this was from dump_prefix_expression, which is only called when expression debugging is enabled. Implementing this would involve a fair amount of code, and it seems to me that prefix dumping is preferable anyway, as it is unambiguous. So, I have not reimplemented this feature. gdb/ChangeLog 2021-03-08 Tom Tromey <tom@tromey.com> * value.h (evaluate_subexp_with_coercion): Don't declare. * parse.c (exp_descriptor_standard): Remove. (expr_builder::expr_builder, expr_builder::release): Update. (expression::expression): Remove size_t parameter. (expression::~expression): Simplify. (expression::resize): Remove. (write_exp_elt, write_exp_elt_opcode, write_exp_elt_sym) (write_exp_elt_msym, write_exp_elt_block, write_exp_elt_objfile) (write_exp_elt_longcst, write_exp_elt_floatcst) (write_exp_elt_type, write_exp_elt_intern, write_exp_string) (write_exp_string_vector, write_exp_bitstring): Remove. * p-lang.h (class pascal_language) <opcode_print_table, op_print_tab>: Remove. * p-lang.c (pascal_language::op_print_tab): Remove. * opencl-lang.c (class opencl_language) <opcode_print_table>: Remove. * objc-lang.c (objc_op_print_tab): Remove. (class objc_language) <opcode_print_table>: Remove. * m2-lang.h (class m2_language) <opcode_print_table, op_print_tab>: Remove. * m2-lang.c (m2_language::op_print_tab): Remove. * language.h (struct language_defn) <post_parser, expression_ops, opcode_print_table>: Remove. * language.c (language_defn::expression_ops) (auto_or_unknown_language::opcode_print_table): Remove. * go-lang.h (class go_language) <opcode_print_table, op_print_tab>: Remove. * go-lang.c (go_language::op_print_tab): Remove. * f-lang.h (class f_language) <opcode_print_table>: Remove <op_print_tab>: Remove. * f-lang.c (f_language::op_print_tab): Remove. * expression.h (union exp_element): Remove. (struct expression): Remove size_t parameter from constructor. <resize>: Remove. <first_opcode>: Update. <nelts, elts>: Remove. (EXP_ELEM_TO_BYTES, BYTES_TO_EXP_ELEM): Remove. (evaluate_subexp_standard, print_expression, op_string) (dump_raw_expression): Don't declare. * expprint.c (print_expression, print_subexp) (print_subexp_funcall, print_subexp_standard, op_string) (dump_raw_expression, dump_subexp, dump_subexp_body) (dump_subexp_body_funcall, dump_subexp_body_standard): Remove. (dump_prefix_expression): Update. * eval.c (evaluate_subexp): Remove. (evaluate_expression, evaluate_type): Update. (evaluate_subexpression_type): Remove. (fetch_subexp_value): Remove "pc" parameter. Update. (extract_field_op, evaluate_struct_tuple, evaluate_funcall) (evaluate_subexp_standard, evaluate_subexp_for_address) (evaluate_subexp_with_coercion, evaluate_subexp_for_sizeof) (evaluate_subexp_for_cast): Remove. (parse_and_eval_type): Update. * dtrace-probe.c (dtrace_probe::compile_to_ax): Update. * d-lang.c (d_op_print_tab): Remove. (class d_language) <opcode_print_table>: Remove. * c-lang.h (c_op_print_tab): Don't declare. * c-lang.c (c_op_print_tab): Remove. (class c_language, class cplus_language, class asm_language, class minimal_language) <opcode_print_table>: Remove. * breakpoint.c (update_watchpoint, watchpoint_check) (watchpoint_exp_is_const, watch_command_1): Update. * ax-gdb.h (union exp_element): Don't declare. * ax-gdb.c (const_var_ref, const_expr, maybe_const_expr) (gen_repeat, gen_sizeof, gen_expr_for_cast, gen_expr) (gen_expr_binop_rest): Remove. (gen_trace_for_expr, gen_eval_for_expr, gen_printf): Update. * ada-lang.c (ada_op_print_tab): Remove. (class ada_language) <post_parser, opcode_print_table>: Remove.
2021-03-08 22:27:57 +08:00
struct value *retval = op->evaluate (expect_type, this, noside);
if (stack_temporaries.has_value ()
&& value_in_thread_stack_temporaries (retval, inferior_thread ()))
retval = retval->non_lval ();
return retval;
}
2010-07-07 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> Support for hw accelerated condition watchpoints in booke powerpc. * breakpoint.c (fetch_watchpoint_value): Rename to fetch_subexp_value and move to eval.c. Change callers. (insert_bp_location): Pass watchpoint condition in target_insert_watchpoint. (remove_breakpoint_1) Pass watchpoint condition in target_remove_watchpoint. (watchpoint_locations_match): Call target_can_accel_watchpoint_condition. * eval.c: Include wrapper.h. (fetch_subexp_value): Moved from breakpoint.c. * ppc-linux-nat.c (ppc_linux_region_ok_for_hw_watchpoint): Formatting fix. (can_use_watchpoint_cond_accel): New function. (calculate_dvc): Likewise. (num_memory_accesses): Likewise. (check_condition): Likewise. (ppc_linux_can_accel_watchpoint_condition): Likewise (ppc_linux_insert_watchpoint): Call can_use_watchpoint_cond_accel, check_condition and calculate_dvc. (ppc_linux_remove_watchpoint): Likewise. (_initialize_ppc_linux_nat): Set to_can_accel_watchpoint_condition to ppc_linux_can_accel_watchpoint_condition * target.c (debug_to_insert_watchpoint): Add argument for watchpoint condition. (debug_to_remove_watchpoint): Likewise. (debug_to_can_accel_watchpoint_condition): New function. (update_current_target): Set to_can_accel_watchpoint_condition. (setup_target_debug): Set to_can_accel_watchpoint_condition. * target.h: Add opaque declaration for struct expression. (struct target_ops) <to_insert_watchpoint>, <to_remove_watchpoint>: Add new arguments to pass the watchpoint <to_can_accel_watchpoint_condition>: New member. condition. Update all callers and implementations. (target_can_accel_watchpoint_condition): New macro. * value.c (free_value_chain): New function. * value.h (fetch_subexp_value): New prototype. (free_value_chain): Likewise.
2010-07-08 00:15:18 +08:00
/* Find the current value of a watchpoint on EXP. Return the value in
*VALP and *RESULTP and the chain of intermediate and final values
in *VAL_CHAIN. RESULTP and VAL_CHAIN may be NULL if the caller does
not need them.
If PRESERVE_ERRORS is true, then exceptions are passed through.
Otherwise, if PRESERVE_ERRORS is false, then if a memory error
occurs while evaluating the expression, *RESULTP will be set to
NULL. *RESULTP may be a lazy value, if the result could not be
read from memory. It is used to determine whether a value is
user-specified (we should watch the whole value) or intermediate
2010-07-07 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> Support for hw accelerated condition watchpoints in booke powerpc. * breakpoint.c (fetch_watchpoint_value): Rename to fetch_subexp_value and move to eval.c. Change callers. (insert_bp_location): Pass watchpoint condition in target_insert_watchpoint. (remove_breakpoint_1) Pass watchpoint condition in target_remove_watchpoint. (watchpoint_locations_match): Call target_can_accel_watchpoint_condition. * eval.c: Include wrapper.h. (fetch_subexp_value): Moved from breakpoint.c. * ppc-linux-nat.c (ppc_linux_region_ok_for_hw_watchpoint): Formatting fix. (can_use_watchpoint_cond_accel): New function. (calculate_dvc): Likewise. (num_memory_accesses): Likewise. (check_condition): Likewise. (ppc_linux_can_accel_watchpoint_condition): Likewise (ppc_linux_insert_watchpoint): Call can_use_watchpoint_cond_accel, check_condition and calculate_dvc. (ppc_linux_remove_watchpoint): Likewise. (_initialize_ppc_linux_nat): Set to_can_accel_watchpoint_condition to ppc_linux_can_accel_watchpoint_condition * target.c (debug_to_insert_watchpoint): Add argument for watchpoint condition. (debug_to_remove_watchpoint): Likewise. (debug_to_can_accel_watchpoint_condition): New function. (update_current_target): Set to_can_accel_watchpoint_condition. (setup_target_debug): Set to_can_accel_watchpoint_condition. * target.h: Add opaque declaration for struct expression. (struct target_ops) <to_insert_watchpoint>, <to_remove_watchpoint>: Add new arguments to pass the watchpoint <to_can_accel_watchpoint_condition>: New member. condition. Update all callers and implementations. (target_can_accel_watchpoint_condition): New macro. * value.c (free_value_chain): New function. * value.h (fetch_subexp_value): New prototype. (free_value_chain): Likewise.
2010-07-08 00:15:18 +08:00
(we should watch only the bit used to locate the final value).
If the final value, or any intermediate value, could not be read
from memory, *VALP will be set to NULL. *VAL_CHAIN will still be
set to any referenced values. *VALP will never be a lazy value.
This is the value which we store in struct breakpoint.
If VAL_CHAIN is non-NULL, the values put into *VAL_CHAIN will be
released from the value chain. If VAL_CHAIN is NULL, all generated
values will be left on the value chain. */
2010-07-07 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> Support for hw accelerated condition watchpoints in booke powerpc. * breakpoint.c (fetch_watchpoint_value): Rename to fetch_subexp_value and move to eval.c. Change callers. (insert_bp_location): Pass watchpoint condition in target_insert_watchpoint. (remove_breakpoint_1) Pass watchpoint condition in target_remove_watchpoint. (watchpoint_locations_match): Call target_can_accel_watchpoint_condition. * eval.c: Include wrapper.h. (fetch_subexp_value): Moved from breakpoint.c. * ppc-linux-nat.c (ppc_linux_region_ok_for_hw_watchpoint): Formatting fix. (can_use_watchpoint_cond_accel): New function. (calculate_dvc): Likewise. (num_memory_accesses): Likewise. (check_condition): Likewise. (ppc_linux_can_accel_watchpoint_condition): Likewise (ppc_linux_insert_watchpoint): Call can_use_watchpoint_cond_accel, check_condition and calculate_dvc. (ppc_linux_remove_watchpoint): Likewise. (_initialize_ppc_linux_nat): Set to_can_accel_watchpoint_condition to ppc_linux_can_accel_watchpoint_condition * target.c (debug_to_insert_watchpoint): Add argument for watchpoint condition. (debug_to_remove_watchpoint): Likewise. (debug_to_can_accel_watchpoint_condition): New function. (update_current_target): Set to_can_accel_watchpoint_condition. (setup_target_debug): Set to_can_accel_watchpoint_condition. * target.h: Add opaque declaration for struct expression. (struct target_ops) <to_insert_watchpoint>, <to_remove_watchpoint>: Add new arguments to pass the watchpoint <to_can_accel_watchpoint_condition>: New member. condition. Update all callers and implementations. (target_can_accel_watchpoint_condition): New macro. * value.c (free_value_chain): New function. * value.h (fetch_subexp_value): New prototype. (free_value_chain): Likewise.
2010-07-08 00:15:18 +08:00
void
Remove union exp_element This removes union exp_element functions that either create such elements or walk them. struct expression no longer holds exp_elements. A couple of language_defn methods are also removed, as they are obsolete. Note that this patch also removes the print_expression code. The only in-tree caller of this was from dump_prefix_expression, which is only called when expression debugging is enabled. Implementing this would involve a fair amount of code, and it seems to me that prefix dumping is preferable anyway, as it is unambiguous. So, I have not reimplemented this feature. gdb/ChangeLog 2021-03-08 Tom Tromey <tom@tromey.com> * value.h (evaluate_subexp_with_coercion): Don't declare. * parse.c (exp_descriptor_standard): Remove. (expr_builder::expr_builder, expr_builder::release): Update. (expression::expression): Remove size_t parameter. (expression::~expression): Simplify. (expression::resize): Remove. (write_exp_elt, write_exp_elt_opcode, write_exp_elt_sym) (write_exp_elt_msym, write_exp_elt_block, write_exp_elt_objfile) (write_exp_elt_longcst, write_exp_elt_floatcst) (write_exp_elt_type, write_exp_elt_intern, write_exp_string) (write_exp_string_vector, write_exp_bitstring): Remove. * p-lang.h (class pascal_language) <opcode_print_table, op_print_tab>: Remove. * p-lang.c (pascal_language::op_print_tab): Remove. * opencl-lang.c (class opencl_language) <opcode_print_table>: Remove. * objc-lang.c (objc_op_print_tab): Remove. (class objc_language) <opcode_print_table>: Remove. * m2-lang.h (class m2_language) <opcode_print_table, op_print_tab>: Remove. * m2-lang.c (m2_language::op_print_tab): Remove. * language.h (struct language_defn) <post_parser, expression_ops, opcode_print_table>: Remove. * language.c (language_defn::expression_ops) (auto_or_unknown_language::opcode_print_table): Remove. * go-lang.h (class go_language) <opcode_print_table, op_print_tab>: Remove. * go-lang.c (go_language::op_print_tab): Remove. * f-lang.h (class f_language) <opcode_print_table>: Remove <op_print_tab>: Remove. * f-lang.c (f_language::op_print_tab): Remove. * expression.h (union exp_element): Remove. (struct expression): Remove size_t parameter from constructor. <resize>: Remove. <first_opcode>: Update. <nelts, elts>: Remove. (EXP_ELEM_TO_BYTES, BYTES_TO_EXP_ELEM): Remove. (evaluate_subexp_standard, print_expression, op_string) (dump_raw_expression): Don't declare. * expprint.c (print_expression, print_subexp) (print_subexp_funcall, print_subexp_standard, op_string) (dump_raw_expression, dump_subexp, dump_subexp_body) (dump_subexp_body_funcall, dump_subexp_body_standard): Remove. (dump_prefix_expression): Update. * eval.c (evaluate_subexp): Remove. (evaluate_expression, evaluate_type): Update. (evaluate_subexpression_type): Remove. (fetch_subexp_value): Remove "pc" parameter. Update. (extract_field_op, evaluate_struct_tuple, evaluate_funcall) (evaluate_subexp_standard, evaluate_subexp_for_address) (evaluate_subexp_with_coercion, evaluate_subexp_for_sizeof) (evaluate_subexp_for_cast): Remove. (parse_and_eval_type): Update. * dtrace-probe.c (dtrace_probe::compile_to_ax): Update. * d-lang.c (d_op_print_tab): Remove. (class d_language) <opcode_print_table>: Remove. * c-lang.h (c_op_print_tab): Don't declare. * c-lang.c (c_op_print_tab): Remove. (class c_language, class cplus_language, class asm_language, class minimal_language) <opcode_print_table>: Remove. * breakpoint.c (update_watchpoint, watchpoint_check) (watchpoint_exp_is_const, watch_command_1): Update. * ax-gdb.h (union exp_element): Don't declare. * ax-gdb.c (const_var_ref, const_expr, maybe_const_expr) (gen_repeat, gen_sizeof, gen_expr_for_cast, gen_expr) (gen_expr_binop_rest): Remove. (gen_trace_for_expr, gen_eval_for_expr, gen_printf): Update. * ada-lang.c (ada_op_print_tab): Remove. (class ada_language) <post_parser, opcode_print_table>: Remove.
2021-03-08 22:27:57 +08:00
fetch_subexp_value (struct expression *exp,
Add an expr::operation_up to struct expression This adds an expr::operation_up to struct expression, and then modifies various parts of GDB to use this member when it is non-null. The list of such spots was a bit surprising to me, and found only after writing most of the code and then noticing what no longer compiled. In a few spots, new accessor methods are added to operation subclasses, so that code that dissects an expression will work with the new scheme. After this change, code that constructs an expression can be switched to the new form without breaking. gdb/ChangeLog 2021-03-08 Tom Tromey <tom@tromey.com> * ada-exp.h (class ada_var_value_operation) <get_symbol>: Remove; now in superclass. * value.h (fetch_subexp_value): Add "op" parameter. * value.c (init_if_undefined_command): Update. * tracepoint.c (validate_actionline, encode_actions_1): Update. * stap-probe.c (stap_probe::compile_to_ax): Update. * printcmd.c (set_command): Update. * ppc-linux-nat.c (ppc_linux_nat_target::check_condition): Update. * parser-defs.h (struct expr_builder) <set_operation>: New method. * parse.c (parse_exp_in_context, exp_uses_objfile): Update. * expression.h (struct expression) <first_opcode>: Update. <op>: New member. * expprint.c (dump_raw_expression, dump_prefix_expression): Update. * expop.h (class var_value_operation) <get_symbol>: New method. (class register_operation) <get_name>: New method. (class equal_operation): No longer a typedef, now a subclass. (class unop_memval_operation) <get_type>: New method. (class assign_operation) <get_lhs>: New method. (class unop_cast_operation) <get_type>: New method. * eval.c (evaluate_expression, evaluate_type) (evaluate_subexpression_type): Update. (fetch_subexp_value): Add "op" parameter. (parse_and_eval_type): Update. * dtrace-probe.c (dtrace_probe::compile_to_ax): Update. * breakpoint.c (update_watchpoint, watchpoint_check) (watchpoint_exp_is_const, watch_command_1): Update. * ax-gdb.c (gen_trace_for_expr, gen_eval_for_expr, gen_printf): Update.
2021-03-08 22:27:57 +08:00
expr::operation *op,
struct value **valp, struct value **resultp,
std::vector<value_ref_ptr> *val_chain,
bool preserve_errors)
2010-07-07 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> Support for hw accelerated condition watchpoints in booke powerpc. * breakpoint.c (fetch_watchpoint_value): Rename to fetch_subexp_value and move to eval.c. Change callers. (insert_bp_location): Pass watchpoint condition in target_insert_watchpoint. (remove_breakpoint_1) Pass watchpoint condition in target_remove_watchpoint. (watchpoint_locations_match): Call target_can_accel_watchpoint_condition. * eval.c: Include wrapper.h. (fetch_subexp_value): Moved from breakpoint.c. * ppc-linux-nat.c (ppc_linux_region_ok_for_hw_watchpoint): Formatting fix. (can_use_watchpoint_cond_accel): New function. (calculate_dvc): Likewise. (num_memory_accesses): Likewise. (check_condition): Likewise. (ppc_linux_can_accel_watchpoint_condition): Likewise (ppc_linux_insert_watchpoint): Call can_use_watchpoint_cond_accel, check_condition and calculate_dvc. (ppc_linux_remove_watchpoint): Likewise. (_initialize_ppc_linux_nat): Set to_can_accel_watchpoint_condition to ppc_linux_can_accel_watchpoint_condition * target.c (debug_to_insert_watchpoint): Add argument for watchpoint condition. (debug_to_remove_watchpoint): Likewise. (debug_to_can_accel_watchpoint_condition): New function. (update_current_target): Set to_can_accel_watchpoint_condition. (setup_target_debug): Set to_can_accel_watchpoint_condition. * target.h: Add opaque declaration for struct expression. (struct target_ops) <to_insert_watchpoint>, <to_remove_watchpoint>: Add new arguments to pass the watchpoint <to_can_accel_watchpoint_condition>: New member. condition. Update all callers and implementations. (target_can_accel_watchpoint_condition): New macro. * value.c (free_value_chain): New function. * value.h (fetch_subexp_value): New prototype. (free_value_chain): Likewise.
2010-07-08 00:15:18 +08:00
{
struct value *mark, *new_mark, *result;
*valp = NULL;
if (resultp)
*resultp = NULL;
if (val_chain)
val_chain->clear ();
2010-07-07 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> Support for hw accelerated condition watchpoints in booke powerpc. * breakpoint.c (fetch_watchpoint_value): Rename to fetch_subexp_value and move to eval.c. Change callers. (insert_bp_location): Pass watchpoint condition in target_insert_watchpoint. (remove_breakpoint_1) Pass watchpoint condition in target_remove_watchpoint. (watchpoint_locations_match): Call target_can_accel_watchpoint_condition. * eval.c: Include wrapper.h. (fetch_subexp_value): Moved from breakpoint.c. * ppc-linux-nat.c (ppc_linux_region_ok_for_hw_watchpoint): Formatting fix. (can_use_watchpoint_cond_accel): New function. (calculate_dvc): Likewise. (num_memory_accesses): Likewise. (check_condition): Likewise. (ppc_linux_can_accel_watchpoint_condition): Likewise (ppc_linux_insert_watchpoint): Call can_use_watchpoint_cond_accel, check_condition and calculate_dvc. (ppc_linux_remove_watchpoint): Likewise. (_initialize_ppc_linux_nat): Set to_can_accel_watchpoint_condition to ppc_linux_can_accel_watchpoint_condition * target.c (debug_to_insert_watchpoint): Add argument for watchpoint condition. (debug_to_remove_watchpoint): Likewise. (debug_to_can_accel_watchpoint_condition): New function. (update_current_target): Set to_can_accel_watchpoint_condition. (setup_target_debug): Set to_can_accel_watchpoint_condition. * target.h: Add opaque declaration for struct expression. (struct target_ops) <to_insert_watchpoint>, <to_remove_watchpoint>: Add new arguments to pass the watchpoint <to_can_accel_watchpoint_condition>: New member. condition. Update all callers and implementations. (target_can_accel_watchpoint_condition): New macro. * value.c (free_value_chain): New function. * value.h (fetch_subexp_value): New prototype. (free_value_chain): Likewise.
2010-07-08 00:15:18 +08:00
/* Evaluate the expression. */
mark = value_mark ();
result = NULL;
Rewrite TRY/CATCH This rewrites gdb's TRY/CATCH to plain C++ try/catch. The patch was largely written by script, though one change (to a comment in common-exceptions.h) was reverted by hand. gdb/ChangeLog 2019-04-08 Tom Tromey <tom@tromey.com> * xml-support.c: Use C++ exception handling. * x86-linux-nat.c: Use C++ exception handling. * windows-nat.c: Use C++ exception handling. * varobj.c: Use C++ exception handling. * value.c: Use C++ exception handling. * valprint.c: Use C++ exception handling. * valops.c: Use C++ exception handling. * unittests/parse-connection-spec-selftests.c: Use C++ exception handling. * unittests/cli-utils-selftests.c: Use C++ exception handling. * typeprint.c: Use C++ exception handling. * tui/tui.c: Use C++ exception handling. * tracefile-tfile.c: Use C++ exception handling. * top.c: Use C++ exception handling. * thread.c: Use C++ exception handling. * target.c: Use C++ exception handling. * symmisc.c: Use C++ exception handling. * symfile-mem.c: Use C++ exception handling. * stack.c: Use C++ exception handling. * sparc64-linux-tdep.c: Use C++ exception handling. * solib.c: Use C++ exception handling. * solib-svr4.c: Use C++ exception handling. * solib-spu.c: Use C++ exception handling. * solib-frv.c: Use C++ exception handling. * solib-dsbt.c: Use C++ exception handling. * selftest-arch.c: Use C++ exception handling. * s390-tdep.c: Use C++ exception handling. * rust-lang.c: Use C++ exception handling. * rust-exp.y: Use C++ exception handling. * rs6000-tdep.c: Use C++ exception handling. * rs6000-aix-tdep.c: Use C++ exception handling. * riscv-tdep.c: Use C++ exception handling. * remote.c: Use C++ exception handling. * remote-fileio.c: Use C++ exception handling. * record-full.c: Use C++ exception handling. * record-btrace.c: Use C++ exception handling. * python/python.c: Use C++ exception handling. * python/py-value.c: Use C++ exception handling. * python/py-utils.c: Use C++ exception handling. * python/py-unwind.c: Use C++ exception handling. * python/py-type.c: Use C++ exception handling. * python/py-symbol.c: Use C++ exception handling. * python/py-record.c: Use C++ exception handling. * python/py-record-btrace.c: Use C++ exception handling. * python/py-progspace.c: Use C++ exception handling. * python/py-prettyprint.c: Use C++ exception handling. * python/py-param.c: Use C++ exception handling. * python/py-objfile.c: Use C++ exception handling. * python/py-linetable.c: Use C++ exception handling. * python/py-lazy-string.c: Use C++ exception handling. * python/py-infthread.c: Use C++ exception handling. * python/py-inferior.c: Use C++ exception handling. * python/py-gdb-readline.c: Use C++ exception handling. * python/py-framefilter.c: Use C++ exception handling. * python/py-frame.c: Use C++ exception handling. * python/py-finishbreakpoint.c: Use C++ exception handling. * python/py-cmd.c: Use C++ exception handling. * python/py-breakpoint.c: Use C++ exception handling. * python/py-arch.c: Use C++ exception handling. * printcmd.c: Use C++ exception handling. * ppc-linux-tdep.c: Use C++ exception handling. * parse.c: Use C++ exception handling. * p-valprint.c: Use C++ exception handling. * objc-lang.c: Use C++ exception handling. * mi/mi-main.c: Use C++ exception handling. * mi/mi-interp.c: Use C++ exception handling. * mi/mi-cmd-stack.c: Use C++ exception handling. * mi/mi-cmd-break.c: Use C++ exception handling. * main.c: Use C++ exception handling. * linux-thread-db.c: Use C++ exception handling. * linux-tdep.c: Use C++ exception handling. * linux-nat.c: Use C++ exception handling. * linux-fork.c: Use C++ exception handling. * linespec.c: Use C++ exception handling. * language.c: Use C++ exception handling. * jit.c: Use C++ exception handling. * infrun.c: Use C++ exception handling. * infcmd.c: Use C++ exception handling. * infcall.c: Use C++ exception handling. * inf-loop.c: Use C++ exception handling. * i386-tdep.c: Use C++ exception handling. * i386-linux-tdep.c: Use C++ exception handling. * guile/scm-value.c: Use C++ exception handling. * guile/scm-type.c: Use C++ exception handling. * guile/scm-symtab.c: Use C++ exception handling. * guile/scm-symbol.c: Use C++ exception handling. * guile/scm-pretty-print.c: Use C++ exception handling. * guile/scm-ports.c: Use C++ exception handling. * guile/scm-param.c: Use C++ exception handling. * guile/scm-math.c: Use C++ exception handling. * guile/scm-lazy-string.c: Use C++ exception handling. * guile/scm-frame.c: Use C++ exception handling. * guile/scm-disasm.c: Use C++ exception handling. * guile/scm-cmd.c: Use C++ exception handling. * guile/scm-breakpoint.c: Use C++ exception handling. * guile/scm-block.c: Use C++ exception handling. * guile/guile-internal.h: Use C++ exception handling. * gnu-v3-abi.c: Use C++ exception handling. * gdbtypes.c: Use C++ exception handling. * frame.c: Use C++ exception handling. * frame-unwind.c: Use C++ exception handling. * fbsd-tdep.c: Use C++ exception handling. * f-valprint.c: Use C++ exception handling. * exec.c: Use C++ exception handling. * event-top.c: Use C++ exception handling. * event-loop.c: Use C++ exception handling. * eval.c: Use C++ exception handling. * dwarf2read.c: Use C++ exception handling. * dwarf2loc.c: Use C++ exception handling. * dwarf2-frame.c: Use C++ exception handling. * dwarf2-frame-tailcall.c: Use C++ exception handling. * dwarf-index-write.c: Use C++ exception handling. * dwarf-index-cache.c: Use C++ exception handling. * dtrace-probe.c: Use C++ exception handling. * disasm-selftests.c: Use C++ exception handling. * darwin-nat.c: Use C++ exception handling. * cp-valprint.c: Use C++ exception handling. * cp-support.c: Use C++ exception handling. * cp-abi.c: Use C++ exception handling. * corelow.c: Use C++ exception handling. * completer.c: Use C++ exception handling. * compile/compile-object-run.c: Use C++ exception handling. * compile/compile-object-load.c: Use C++ exception handling. * compile/compile-cplus-symbols.c: Use C++ exception handling. * compile/compile-c-symbols.c: Use C++ exception handling. * common/selftest.c: Use C++ exception handling. * common/new-op.c: Use C++ exception handling. * cli/cli-script.c: Use C++ exception handling. * cli/cli-interp.c: Use C++ exception handling. * cli/cli-cmds.c: Use C++ exception handling. * c-varobj.c: Use C++ exception handling. * btrace.c: Use C++ exception handling. * breakpoint.c: Use C++ exception handling. * break-catch-throw.c: Use C++ exception handling. * arch-utils.c: Use C++ exception handling. * amd64-tdep.c: Use C++ exception handling. * ada-valprint.c: Use C++ exception handling. * ada-typeprint.c: Use C++ exception handling. * ada-lang.c: Use C++ exception handling. * aarch64-tdep.c: Use C++ exception handling. gdb/gdbserver/ChangeLog 2019-04-08 Tom Tromey <tom@tromey.com> * server.c: Use C++ exception handling. * linux-low.c: Use C++ exception handling. * gdbreplay.c: Use C++ exception handling.
2019-04-04 06:02:42 +08:00
try
2010-07-07 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> Support for hw accelerated condition watchpoints in booke powerpc. * breakpoint.c (fetch_watchpoint_value): Rename to fetch_subexp_value and move to eval.c. Change callers. (insert_bp_location): Pass watchpoint condition in target_insert_watchpoint. (remove_breakpoint_1) Pass watchpoint condition in target_remove_watchpoint. (watchpoint_locations_match): Call target_can_accel_watchpoint_condition. * eval.c: Include wrapper.h. (fetch_subexp_value): Moved from breakpoint.c. * ppc-linux-nat.c (ppc_linux_region_ok_for_hw_watchpoint): Formatting fix. (can_use_watchpoint_cond_accel): New function. (calculate_dvc): Likewise. (num_memory_accesses): Likewise. (check_condition): Likewise. (ppc_linux_can_accel_watchpoint_condition): Likewise (ppc_linux_insert_watchpoint): Call can_use_watchpoint_cond_accel, check_condition and calculate_dvc. (ppc_linux_remove_watchpoint): Likewise. (_initialize_ppc_linux_nat): Set to_can_accel_watchpoint_condition to ppc_linux_can_accel_watchpoint_condition * target.c (debug_to_insert_watchpoint): Add argument for watchpoint condition. (debug_to_remove_watchpoint): Likewise. (debug_to_can_accel_watchpoint_condition): New function. (update_current_target): Set to_can_accel_watchpoint_condition. (setup_target_debug): Set to_can_accel_watchpoint_condition. * target.h: Add opaque declaration for struct expression. (struct target_ops) <to_insert_watchpoint>, <to_remove_watchpoint>: Add new arguments to pass the watchpoint <to_can_accel_watchpoint_condition>: New member. condition. Update all callers and implementations. (target_can_accel_watchpoint_condition): New macro. * value.c (free_value_chain): New function. * value.h (fetch_subexp_value): New prototype. (free_value_chain): Likewise.
2010-07-08 00:15:18 +08:00
{
Remove union exp_element This removes union exp_element functions that either create such elements or walk them. struct expression no longer holds exp_elements. A couple of language_defn methods are also removed, as they are obsolete. Note that this patch also removes the print_expression code. The only in-tree caller of this was from dump_prefix_expression, which is only called when expression debugging is enabled. Implementing this would involve a fair amount of code, and it seems to me that prefix dumping is preferable anyway, as it is unambiguous. So, I have not reimplemented this feature. gdb/ChangeLog 2021-03-08 Tom Tromey <tom@tromey.com> * value.h (evaluate_subexp_with_coercion): Don't declare. * parse.c (exp_descriptor_standard): Remove. (expr_builder::expr_builder, expr_builder::release): Update. (expression::expression): Remove size_t parameter. (expression::~expression): Simplify. (expression::resize): Remove. (write_exp_elt, write_exp_elt_opcode, write_exp_elt_sym) (write_exp_elt_msym, write_exp_elt_block, write_exp_elt_objfile) (write_exp_elt_longcst, write_exp_elt_floatcst) (write_exp_elt_type, write_exp_elt_intern, write_exp_string) (write_exp_string_vector, write_exp_bitstring): Remove. * p-lang.h (class pascal_language) <opcode_print_table, op_print_tab>: Remove. * p-lang.c (pascal_language::op_print_tab): Remove. * opencl-lang.c (class opencl_language) <opcode_print_table>: Remove. * objc-lang.c (objc_op_print_tab): Remove. (class objc_language) <opcode_print_table>: Remove. * m2-lang.h (class m2_language) <opcode_print_table, op_print_tab>: Remove. * m2-lang.c (m2_language::op_print_tab): Remove. * language.h (struct language_defn) <post_parser, expression_ops, opcode_print_table>: Remove. * language.c (language_defn::expression_ops) (auto_or_unknown_language::opcode_print_table): Remove. * go-lang.h (class go_language) <opcode_print_table, op_print_tab>: Remove. * go-lang.c (go_language::op_print_tab): Remove. * f-lang.h (class f_language) <opcode_print_table>: Remove <op_print_tab>: Remove. * f-lang.c (f_language::op_print_tab): Remove. * expression.h (union exp_element): Remove. (struct expression): Remove size_t parameter from constructor. <resize>: Remove. <first_opcode>: Update. <nelts, elts>: Remove. (EXP_ELEM_TO_BYTES, BYTES_TO_EXP_ELEM): Remove. (evaluate_subexp_standard, print_expression, op_string) (dump_raw_expression): Don't declare. * expprint.c (print_expression, print_subexp) (print_subexp_funcall, print_subexp_standard, op_string) (dump_raw_expression, dump_subexp, dump_subexp_body) (dump_subexp_body_funcall, dump_subexp_body_standard): Remove. (dump_prefix_expression): Update. * eval.c (evaluate_subexp): Remove. (evaluate_expression, evaluate_type): Update. (evaluate_subexpression_type): Remove. (fetch_subexp_value): Remove "pc" parameter. Update. (extract_field_op, evaluate_struct_tuple, evaluate_funcall) (evaluate_subexp_standard, evaluate_subexp_for_address) (evaluate_subexp_with_coercion, evaluate_subexp_for_sizeof) (evaluate_subexp_for_cast): Remove. (parse_and_eval_type): Update. * dtrace-probe.c (dtrace_probe::compile_to_ax): Update. * d-lang.c (d_op_print_tab): Remove. (class d_language) <opcode_print_table>: Remove. * c-lang.h (c_op_print_tab): Don't declare. * c-lang.c (c_op_print_tab): Remove. (class c_language, class cplus_language, class asm_language, class minimal_language) <opcode_print_table>: Remove. * breakpoint.c (update_watchpoint, watchpoint_check) (watchpoint_exp_is_const, watch_command_1): Update. * ax-gdb.h (union exp_element): Don't declare. * ax-gdb.c (const_var_ref, const_expr, maybe_const_expr) (gen_repeat, gen_sizeof, gen_expr_for_cast, gen_expr) (gen_expr_binop_rest): Remove. (gen_trace_for_expr, gen_eval_for_expr, gen_printf): Update. * ada-lang.c (ada_op_print_tab): Remove. (class ada_language) <post_parser, opcode_print_table>: Remove.
2021-03-08 22:27:57 +08:00
result = op->evaluate (nullptr, exp, EVAL_NORMAL);
2010-07-07 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> Support for hw accelerated condition watchpoints in booke powerpc. * breakpoint.c (fetch_watchpoint_value): Rename to fetch_subexp_value and move to eval.c. Change callers. (insert_bp_location): Pass watchpoint condition in target_insert_watchpoint. (remove_breakpoint_1) Pass watchpoint condition in target_remove_watchpoint. (watchpoint_locations_match): Call target_can_accel_watchpoint_condition. * eval.c: Include wrapper.h. (fetch_subexp_value): Moved from breakpoint.c. * ppc-linux-nat.c (ppc_linux_region_ok_for_hw_watchpoint): Formatting fix. (can_use_watchpoint_cond_accel): New function. (calculate_dvc): Likewise. (num_memory_accesses): Likewise. (check_condition): Likewise. (ppc_linux_can_accel_watchpoint_condition): Likewise (ppc_linux_insert_watchpoint): Call can_use_watchpoint_cond_accel, check_condition and calculate_dvc. (ppc_linux_remove_watchpoint): Likewise. (_initialize_ppc_linux_nat): Set to_can_accel_watchpoint_condition to ppc_linux_can_accel_watchpoint_condition * target.c (debug_to_insert_watchpoint): Add argument for watchpoint condition. (debug_to_remove_watchpoint): Likewise. (debug_to_can_accel_watchpoint_condition): New function. (update_current_target): Set to_can_accel_watchpoint_condition. (setup_target_debug): Set to_can_accel_watchpoint_condition. * target.h: Add opaque declaration for struct expression. (struct target_ops) <to_insert_watchpoint>, <to_remove_watchpoint>: Add new arguments to pass the watchpoint <to_can_accel_watchpoint_condition>: New member. condition. Update all callers and implementations. (target_can_accel_watchpoint_condition): New macro. * value.c (free_value_chain): New function. * value.h (fetch_subexp_value): New prototype. (free_value_chain): Likewise.
2010-07-08 00:15:18 +08:00
}
Rename gdb exception types This renames the gdb exception types. The old types were only needed due to the macros in common-exception.h that are now gone. The intermediate layer of gdb_exception_RETURN_MASK_ALL did not seem needed, so this patch removes it entirely. gdb/ChangeLog 2019-04-08 Tom Tromey <tom@tromey.com> * common/common-exceptions.h (gdb_exception_RETURN_MASK_ALL): Remove. (gdb_exception_error): Rename from gdb_exception_RETURN_MASK_ERROR. (gdb_exception_quit): Rename from gdb_exception_RETURN_MASK_QUIT. (gdb_quit_bad_alloc): Update. * aarch64-tdep.c: Update. * ada-lang.c: Update. * ada-typeprint.c: Update. * ada-valprint.c: Update. * amd64-tdep.c: Update. * arch-utils.c: Update. * break-catch-throw.c: Update. * breakpoint.c: Update. * btrace.c: Update. * c-varobj.c: Update. * cli/cli-cmds.c: Update. * cli/cli-interp.c: Update. * cli/cli-script.c: Update. * common/common-exceptions.c: Update. * common/new-op.c: Update. * common/selftest.c: Update. * compile/compile-c-symbols.c: Update. * compile/compile-cplus-symbols.c: Update. * compile/compile-object-load.c: Update. * compile/compile-object-run.c: Update. * completer.c: Update. * corelow.c: Update. * cp-abi.c: Update. * cp-support.c: Update. * cp-valprint.c: Update. * darwin-nat.c: Update. * disasm-selftests.c: Update. * dtrace-probe.c: Update. * dwarf-index-cache.c: Update. * dwarf-index-write.c: Update. * dwarf2-frame-tailcall.c: Update. * dwarf2-frame.c: Update. * dwarf2loc.c: Update. * dwarf2read.c: Update. * eval.c: Update. * event-loop.c: Update. * event-top.c: Update. * exec.c: Update. * f-valprint.c: Update. * fbsd-tdep.c: Update. * frame-unwind.c: Update. * frame.c: Update. * gdbtypes.c: Update. * gnu-v3-abi.c: Update. * guile/guile-internal.h: Update. * guile/scm-block.c: Update. * guile/scm-breakpoint.c: Update. * guile/scm-cmd.c: Update. * guile/scm-disasm.c: Update. * guile/scm-frame.c: Update. * guile/scm-lazy-string.c: Update. * guile/scm-math.c: Update. * guile/scm-param.c: Update. * guile/scm-ports.c: Update. * guile/scm-pretty-print.c: Update. * guile/scm-symbol.c: Update. * guile/scm-symtab.c: Update. * guile/scm-type.c: Update. * guile/scm-value.c: Update. * i386-linux-tdep.c: Update. * i386-tdep.c: Update. * inf-loop.c: Update. * infcall.c: Update. * infcmd.c: Update. * infrun.c: Update. * jit.c: Update. * language.c: Update. * linespec.c: Update. * linux-fork.c: Update. * linux-nat.c: Update. * linux-tdep.c: Update. * linux-thread-db.c: Update. * main.c: Update. * mi/mi-cmd-break.c: Update. * mi/mi-cmd-stack.c: Update. * mi/mi-interp.c: Update. * mi/mi-main.c: Update. * objc-lang.c: Update. * p-valprint.c: Update. * parse.c: Update. * ppc-linux-tdep.c: Update. * printcmd.c: Update. * python/py-arch.c: Update. * python/py-breakpoint.c: Update. * python/py-cmd.c: Update. * python/py-finishbreakpoint.c: Update. * python/py-frame.c: Update. * python/py-framefilter.c: Update. * python/py-gdb-readline.c: Update. * python/py-inferior.c: Update. * python/py-infthread.c: Update. * python/py-lazy-string.c: Update. * python/py-linetable.c: Update. * python/py-objfile.c: Update. * python/py-param.c: Update. * python/py-prettyprint.c: Update. * python/py-progspace.c: Update. * python/py-record-btrace.c: Update. * python/py-record.c: Update. * python/py-symbol.c: Update. * python/py-type.c: Update. * python/py-unwind.c: Update. * python/py-utils.c: Update. * python/py-value.c: Update. * python/python.c: Update. * record-btrace.c: Update. * record-full.c: Update. * remote-fileio.c: Update. * remote.c: Update. * riscv-tdep.c: Update. * rs6000-aix-tdep.c: Update. * rs6000-tdep.c: Update. * rust-exp.y: Update. * rust-lang.c: Update. * s390-tdep.c: Update. * selftest-arch.c: Update. * solib-dsbt.c: Update. * solib-frv.c: Update. * solib-spu.c: Update. * solib-svr4.c: Update. * solib.c: Update. * sparc64-linux-tdep.c: Update. * stack.c: Update. * symfile-mem.c: Update. * symmisc.c: Update. * target.c: Update. * thread.c: Update. * top.c: Update. * tracefile-tfile.c: Update. * tui/tui.c: Update. * typeprint.c: Update. * unittests/cli-utils-selftests.c: Update. * unittests/parse-connection-spec-selftests.c: Update. * valops.c: Update. * valprint.c: Update. * value.c: Update. * varobj.c: Update. * windows-nat.c: Update. * x86-linux-nat.c: Update. * xml-support.c: Update. gdb/gdbserver/ChangeLog 2019-04-08 Tom Tromey <tom@tromey.com> * gdbreplay.c: Update. * linux-low.c: Update. * server.c: Update.
2019-04-04 05:59:07 +08:00
catch (const gdb_exception &ex)
2010-07-07 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> Support for hw accelerated condition watchpoints in booke powerpc. * breakpoint.c (fetch_watchpoint_value): Rename to fetch_subexp_value and move to eval.c. Change callers. (insert_bp_location): Pass watchpoint condition in target_insert_watchpoint. (remove_breakpoint_1) Pass watchpoint condition in target_remove_watchpoint. (watchpoint_locations_match): Call target_can_accel_watchpoint_condition. * eval.c: Include wrapper.h. (fetch_subexp_value): Moved from breakpoint.c. * ppc-linux-nat.c (ppc_linux_region_ok_for_hw_watchpoint): Formatting fix. (can_use_watchpoint_cond_accel): New function. (calculate_dvc): Likewise. (num_memory_accesses): Likewise. (check_condition): Likewise. (ppc_linux_can_accel_watchpoint_condition): Likewise (ppc_linux_insert_watchpoint): Call can_use_watchpoint_cond_accel, check_condition and calculate_dvc. (ppc_linux_remove_watchpoint): Likewise. (_initialize_ppc_linux_nat): Set to_can_accel_watchpoint_condition to ppc_linux_can_accel_watchpoint_condition * target.c (debug_to_insert_watchpoint): Add argument for watchpoint condition. (debug_to_remove_watchpoint): Likewise. (debug_to_can_accel_watchpoint_condition): New function. (update_current_target): Set to_can_accel_watchpoint_condition. (setup_target_debug): Set to_can_accel_watchpoint_condition. * target.h: Add opaque declaration for struct expression. (struct target_ops) <to_insert_watchpoint>, <to_remove_watchpoint>: Add new arguments to pass the watchpoint <to_can_accel_watchpoint_condition>: New member. condition. Update all callers and implementations. (target_can_accel_watchpoint_condition): New macro. * value.c (free_value_chain): New function. * value.h (fetch_subexp_value): New prototype. (free_value_chain): Likewise.
2010-07-08 00:15:18 +08:00
{
/* Ignore memory errors if we want watchpoints pointing at
2010-07-07 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> Support for hw accelerated condition watchpoints in booke powerpc. * breakpoint.c (fetch_watchpoint_value): Rename to fetch_subexp_value and move to eval.c. Change callers. (insert_bp_location): Pass watchpoint condition in target_insert_watchpoint. (remove_breakpoint_1) Pass watchpoint condition in target_remove_watchpoint. (watchpoint_locations_match): Call target_can_accel_watchpoint_condition. * eval.c: Include wrapper.h. (fetch_subexp_value): Moved from breakpoint.c. * ppc-linux-nat.c (ppc_linux_region_ok_for_hw_watchpoint): Formatting fix. (can_use_watchpoint_cond_accel): New function. (calculate_dvc): Likewise. (num_memory_accesses): Likewise. (check_condition): Likewise. (ppc_linux_can_accel_watchpoint_condition): Likewise (ppc_linux_insert_watchpoint): Call can_use_watchpoint_cond_accel, check_condition and calculate_dvc. (ppc_linux_remove_watchpoint): Likewise. (_initialize_ppc_linux_nat): Set to_can_accel_watchpoint_condition to ppc_linux_can_accel_watchpoint_condition * target.c (debug_to_insert_watchpoint): Add argument for watchpoint condition. (debug_to_remove_watchpoint): Likewise. (debug_to_can_accel_watchpoint_condition): New function. (update_current_target): Set to_can_accel_watchpoint_condition. (setup_target_debug): Set to_can_accel_watchpoint_condition. * target.h: Add opaque declaration for struct expression. (struct target_ops) <to_insert_watchpoint>, <to_remove_watchpoint>: Add new arguments to pass the watchpoint <to_can_accel_watchpoint_condition>: New member. condition. Update all callers and implementations. (target_can_accel_watchpoint_condition): New macro. * value.c (free_value_chain): New function. * value.h (fetch_subexp_value): New prototype. (free_value_chain): Likewise.
2010-07-08 00:15:18 +08:00
inaccessible memory to still be created; otherwise, throw the
error to some higher catcher. */
switch (ex.error)
{
case MEMORY_ERROR:
if (!preserve_errors)
break;
[[fallthrough]];
2010-07-07 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> Support for hw accelerated condition watchpoints in booke powerpc. * breakpoint.c (fetch_watchpoint_value): Rename to fetch_subexp_value and move to eval.c. Change callers. (insert_bp_location): Pass watchpoint condition in target_insert_watchpoint. (remove_breakpoint_1) Pass watchpoint condition in target_remove_watchpoint. (watchpoint_locations_match): Call target_can_accel_watchpoint_condition. * eval.c: Include wrapper.h. (fetch_subexp_value): Moved from breakpoint.c. * ppc-linux-nat.c (ppc_linux_region_ok_for_hw_watchpoint): Formatting fix. (can_use_watchpoint_cond_accel): New function. (calculate_dvc): Likewise. (num_memory_accesses): Likewise. (check_condition): Likewise. (ppc_linux_can_accel_watchpoint_condition): Likewise (ppc_linux_insert_watchpoint): Call can_use_watchpoint_cond_accel, check_condition and calculate_dvc. (ppc_linux_remove_watchpoint): Likewise. (_initialize_ppc_linux_nat): Set to_can_accel_watchpoint_condition to ppc_linux_can_accel_watchpoint_condition * target.c (debug_to_insert_watchpoint): Add argument for watchpoint condition. (debug_to_remove_watchpoint): Likewise. (debug_to_can_accel_watchpoint_condition): New function. (update_current_target): Set to_can_accel_watchpoint_condition. (setup_target_debug): Set to_can_accel_watchpoint_condition. * target.h: Add opaque declaration for struct expression. (struct target_ops) <to_insert_watchpoint>, <to_remove_watchpoint>: Add new arguments to pass the watchpoint <to_can_accel_watchpoint_condition>: New member. condition. Update all callers and implementations. (target_can_accel_watchpoint_condition): New macro. * value.c (free_value_chain): New function. * value.h (fetch_subexp_value): New prototype. (free_value_chain): Likewise.
2010-07-08 00:15:18 +08:00
default:
Replace throw_exception with throw in some cases This replaces throw_exception with "throw;" when possible. This was written by script. The rule that is followed is that uses of the form: catch (... &name) { ... throw_exception (name); } ... can be rewritten. This should always be safe, because exceptions are caught by const reference, and therefore can't be modified in the body of the catch. gdb/ChangeLog 2019-04-08 Tom Tromey <tom@tromey.com> * valops.c (value_rtti_indirect_type): Replace throw_exception with throw. * tracefile-tfile.c (tfile_target_open): Replace throw_exception with throw. * thread.c (thr_try_catch_cmd): Replace throw_exception with throw. * target.c (target_translate_tls_address): Replace throw_exception with throw. * stack.c (frame_apply_command_count): Replace throw_exception with throw. * solib-spu.c (append_ocl_sos): Replace throw_exception with throw. * s390-tdep.c (s390_frame_unwind_cache): Replace throw_exception with throw. * rs6000-tdep.c (rs6000_frame_cache) (rs6000_epilogue_frame_cache): Replace throw_exception with throw. * remote.c: Replace throw_exception with throw. * record-full.c (record_full_message, record_full_wait_1) (record_full_restore): Replace throw_exception with throw. * record-btrace.c: (get_thread_current_frame_id, record_btrace_start_replaying) (cmd_record_btrace_bts_start, cmd_record_btrace_pt_start) (cmd_record_btrace_start): Replace throw_exception with throw. * parse.c (parse_exp_in_context_1): Replace throw_exception with throw. * linux-nat.c (detach_one_lwp, linux_resume_one_lwp) (resume_stopped_resumed_lwps): Replace throw_exception with throw. * linespec.c: (find_linespec_symbols): Replace throw_exception with throw. * infrun.c (displaced_step_prepare, resume): Replace throw_exception with throw. * infcmd.c (post_create_inferior): Replace throw_exception with throw. * inf-loop.c (inferior_event_handler): Replace throw_exception with throw. * i386-tdep.c (i386_frame_cache, i386_epilogue_frame_cache) (i386_sigtramp_frame_cache): Replace throw_exception with throw. * frame.c (frame_unwind_pc, get_prev_frame_if_no_cycle) (get_prev_frame_always, get_frame_pc_if_available) (get_frame_address_in_block_if_available, get_frame_language): Replace throw_exception with throw. * frame-unwind.c (frame_unwind_try_unwinder): Replace throw_exception with throw. * eval.c (fetch_subexp_value, evaluate_var_value) (evaluate_funcall, evaluate_subexp_standard): Replace throw_exception with throw. * dwarf2loc.c (call_site_find_chain) (dwarf2_evaluate_loc_desc_full, dwarf2_locexpr_baton_eval): Replace throw_exception with throw. * dwarf2-frame.c (dwarf2_frame_cache): Replace throw_exception with throw. * darwin-nat.c (darwin_attach_pid): Replace throw_exception with throw. * cp-abi.c (baseclass_offset): Replace throw_exception with throw. * completer.c (complete_line_internal): Replace throw_exception with throw. * compile/compile-object-run.c (compile_object_run): Replace throw_exception with throw. * cli/cli-script.c (process_next_line): Replace throw_exception with throw. * btrace.c (btrace_compute_ftrace_pt, btrace_compute_ftrace) (btrace_enable, btrace_maint_update_pt_packets): Replace throw_exception with throw. * breakpoint.c (create_breakpoint, save_breakpoints): Replace throw_exception with throw. * break-catch-throw.c (re_set_exception_catchpoint): Replace throw_exception with throw. * amd64-tdep.c (amd64_frame_cache, amd64_sigtramp_frame_cache) (amd64_epilogue_frame_cache): Replace throw_exception with throw. * aarch64-tdep.c (aarch64_make_prologue_cache) (aarch64_make_stub_cache): Replace throw_exception with throw. gdb/gdbserver/ChangeLog 2019-04-08 Tom Tromey <tom@tromey.com> * linux-low.c (linux_detach_one_lwp): Replace throw_exception with throw. (linux_resume_one_lwp): Likewise.
2019-01-29 01:45:45 +08:00
throw;
2010-07-07 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> Support for hw accelerated condition watchpoints in booke powerpc. * breakpoint.c (fetch_watchpoint_value): Rename to fetch_subexp_value and move to eval.c. Change callers. (insert_bp_location): Pass watchpoint condition in target_insert_watchpoint. (remove_breakpoint_1) Pass watchpoint condition in target_remove_watchpoint. (watchpoint_locations_match): Call target_can_accel_watchpoint_condition. * eval.c: Include wrapper.h. (fetch_subexp_value): Moved from breakpoint.c. * ppc-linux-nat.c (ppc_linux_region_ok_for_hw_watchpoint): Formatting fix. (can_use_watchpoint_cond_accel): New function. (calculate_dvc): Likewise. (num_memory_accesses): Likewise. (check_condition): Likewise. (ppc_linux_can_accel_watchpoint_condition): Likewise (ppc_linux_insert_watchpoint): Call can_use_watchpoint_cond_accel, check_condition and calculate_dvc. (ppc_linux_remove_watchpoint): Likewise. (_initialize_ppc_linux_nat): Set to_can_accel_watchpoint_condition to ppc_linux_can_accel_watchpoint_condition * target.c (debug_to_insert_watchpoint): Add argument for watchpoint condition. (debug_to_remove_watchpoint): Likewise. (debug_to_can_accel_watchpoint_condition): New function. (update_current_target): Set to_can_accel_watchpoint_condition. (setup_target_debug): Set to_can_accel_watchpoint_condition. * target.h: Add opaque declaration for struct expression. (struct target_ops) <to_insert_watchpoint>, <to_remove_watchpoint>: Add new arguments to pass the watchpoint <to_can_accel_watchpoint_condition>: New member. condition. Update all callers and implementations. (target_can_accel_watchpoint_condition): New macro. * value.c (free_value_chain): New function. * value.h (fetch_subexp_value): New prototype. (free_value_chain): Likewise.
2010-07-08 00:15:18 +08:00
break;
}
}
new_mark = value_mark ();
if (mark == new_mark)
return;
if (resultp)
*resultp = result;
/* Make sure it's not lazy, so that after the target stops again we
have a non-lazy previous value to compare with. */
if (result != NULL)
{
if (!result->lazy ())
*valp = result;
else
{
Rewrite TRY/CATCH This rewrites gdb's TRY/CATCH to plain C++ try/catch. The patch was largely written by script, though one change (to a comment in common-exceptions.h) was reverted by hand. gdb/ChangeLog 2019-04-08 Tom Tromey <tom@tromey.com> * xml-support.c: Use C++ exception handling. * x86-linux-nat.c: Use C++ exception handling. * windows-nat.c: Use C++ exception handling. * varobj.c: Use C++ exception handling. * value.c: Use C++ exception handling. * valprint.c: Use C++ exception handling. * valops.c: Use C++ exception handling. * unittests/parse-connection-spec-selftests.c: Use C++ exception handling. * unittests/cli-utils-selftests.c: Use C++ exception handling. * typeprint.c: Use C++ exception handling. * tui/tui.c: Use C++ exception handling. * tracefile-tfile.c: Use C++ exception handling. * top.c: Use C++ exception handling. * thread.c: Use C++ exception handling. * target.c: Use C++ exception handling. * symmisc.c: Use C++ exception handling. * symfile-mem.c: Use C++ exception handling. * stack.c: Use C++ exception handling. * sparc64-linux-tdep.c: Use C++ exception handling. * solib.c: Use C++ exception handling. * solib-svr4.c: Use C++ exception handling. * solib-spu.c: Use C++ exception handling. * solib-frv.c: Use C++ exception handling. * solib-dsbt.c: Use C++ exception handling. * selftest-arch.c: Use C++ exception handling. * s390-tdep.c: Use C++ exception handling. * rust-lang.c: Use C++ exception handling. * rust-exp.y: Use C++ exception handling. * rs6000-tdep.c: Use C++ exception handling. * rs6000-aix-tdep.c: Use C++ exception handling. * riscv-tdep.c: Use C++ exception handling. * remote.c: Use C++ exception handling. * remote-fileio.c: Use C++ exception handling. * record-full.c: Use C++ exception handling. * record-btrace.c: Use C++ exception handling. * python/python.c: Use C++ exception handling. * python/py-value.c: Use C++ exception handling. * python/py-utils.c: Use C++ exception handling. * python/py-unwind.c: Use C++ exception handling. * python/py-type.c: Use C++ exception handling. * python/py-symbol.c: Use C++ exception handling. * python/py-record.c: Use C++ exception handling. * python/py-record-btrace.c: Use C++ exception handling. * python/py-progspace.c: Use C++ exception handling. * python/py-prettyprint.c: Use C++ exception handling. * python/py-param.c: Use C++ exception handling. * python/py-objfile.c: Use C++ exception handling. * python/py-linetable.c: Use C++ exception handling. * python/py-lazy-string.c: Use C++ exception handling. * python/py-infthread.c: Use C++ exception handling. * python/py-inferior.c: Use C++ exception handling. * python/py-gdb-readline.c: Use C++ exception handling. * python/py-framefilter.c: Use C++ exception handling. * python/py-frame.c: Use C++ exception handling. * python/py-finishbreakpoint.c: Use C++ exception handling. * python/py-cmd.c: Use C++ exception handling. * python/py-breakpoint.c: Use C++ exception handling. * python/py-arch.c: Use C++ exception handling. * printcmd.c: Use C++ exception handling. * ppc-linux-tdep.c: Use C++ exception handling. * parse.c: Use C++ exception handling. * p-valprint.c: Use C++ exception handling. * objc-lang.c: Use C++ exception handling. * mi/mi-main.c: Use C++ exception handling. * mi/mi-interp.c: Use C++ exception handling. * mi/mi-cmd-stack.c: Use C++ exception handling. * mi/mi-cmd-break.c: Use C++ exception handling. * main.c: Use C++ exception handling. * linux-thread-db.c: Use C++ exception handling. * linux-tdep.c: Use C++ exception handling. * linux-nat.c: Use C++ exception handling. * linux-fork.c: Use C++ exception handling. * linespec.c: Use C++ exception handling. * language.c: Use C++ exception handling. * jit.c: Use C++ exception handling. * infrun.c: Use C++ exception handling. * infcmd.c: Use C++ exception handling. * infcall.c: Use C++ exception handling. * inf-loop.c: Use C++ exception handling. * i386-tdep.c: Use C++ exception handling. * i386-linux-tdep.c: Use C++ exception handling. * guile/scm-value.c: Use C++ exception handling. * guile/scm-type.c: Use C++ exception handling. * guile/scm-symtab.c: Use C++ exception handling. * guile/scm-symbol.c: Use C++ exception handling. * guile/scm-pretty-print.c: Use C++ exception handling. * guile/scm-ports.c: Use C++ exception handling. * guile/scm-param.c: Use C++ exception handling. * guile/scm-math.c: Use C++ exception handling. * guile/scm-lazy-string.c: Use C++ exception handling. * guile/scm-frame.c: Use C++ exception handling. * guile/scm-disasm.c: Use C++ exception handling. * guile/scm-cmd.c: Use C++ exception handling. * guile/scm-breakpoint.c: Use C++ exception handling. * guile/scm-block.c: Use C++ exception handling. * guile/guile-internal.h: Use C++ exception handling. * gnu-v3-abi.c: Use C++ exception handling. * gdbtypes.c: Use C++ exception handling. * frame.c: Use C++ exception handling. * frame-unwind.c: Use C++ exception handling. * fbsd-tdep.c: Use C++ exception handling. * f-valprint.c: Use C++ exception handling. * exec.c: Use C++ exception handling. * event-top.c: Use C++ exception handling. * event-loop.c: Use C++ exception handling. * eval.c: Use C++ exception handling. * dwarf2read.c: Use C++ exception handling. * dwarf2loc.c: Use C++ exception handling. * dwarf2-frame.c: Use C++ exception handling. * dwarf2-frame-tailcall.c: Use C++ exception handling. * dwarf-index-write.c: Use C++ exception handling. * dwarf-index-cache.c: Use C++ exception handling. * dtrace-probe.c: Use C++ exception handling. * disasm-selftests.c: Use C++ exception handling. * darwin-nat.c: Use C++ exception handling. * cp-valprint.c: Use C++ exception handling. * cp-support.c: Use C++ exception handling. * cp-abi.c: Use C++ exception handling. * corelow.c: Use C++ exception handling. * completer.c: Use C++ exception handling. * compile/compile-object-run.c: Use C++ exception handling. * compile/compile-object-load.c: Use C++ exception handling. * compile/compile-cplus-symbols.c: Use C++ exception handling. * compile/compile-c-symbols.c: Use C++ exception handling. * common/selftest.c: Use C++ exception handling. * common/new-op.c: Use C++ exception handling. * cli/cli-script.c: Use C++ exception handling. * cli/cli-interp.c: Use C++ exception handling. * cli/cli-cmds.c: Use C++ exception handling. * c-varobj.c: Use C++ exception handling. * btrace.c: Use C++ exception handling. * breakpoint.c: Use C++ exception handling. * break-catch-throw.c: Use C++ exception handling. * arch-utils.c: Use C++ exception handling. * amd64-tdep.c: Use C++ exception handling. * ada-valprint.c: Use C++ exception handling. * ada-typeprint.c: Use C++ exception handling. * ada-lang.c: Use C++ exception handling. * aarch64-tdep.c: Use C++ exception handling. gdb/gdbserver/ChangeLog 2019-04-08 Tom Tromey <tom@tromey.com> * server.c: Use C++ exception handling. * linux-low.c: Use C++ exception handling. * gdbreplay.c: Use C++ exception handling.
2019-04-04 06:02:42 +08:00
try
{
result->fetch_lazy ();
*valp = result;
}
Rename gdb exception types This renames the gdb exception types. The old types were only needed due to the macros in common-exception.h that are now gone. The intermediate layer of gdb_exception_RETURN_MASK_ALL did not seem needed, so this patch removes it entirely. gdb/ChangeLog 2019-04-08 Tom Tromey <tom@tromey.com> * common/common-exceptions.h (gdb_exception_RETURN_MASK_ALL): Remove. (gdb_exception_error): Rename from gdb_exception_RETURN_MASK_ERROR. (gdb_exception_quit): Rename from gdb_exception_RETURN_MASK_QUIT. (gdb_quit_bad_alloc): Update. * aarch64-tdep.c: Update. * ada-lang.c: Update. * ada-typeprint.c: Update. * ada-valprint.c: Update. * amd64-tdep.c: Update. * arch-utils.c: Update. * break-catch-throw.c: Update. * breakpoint.c: Update. * btrace.c: Update. * c-varobj.c: Update. * cli/cli-cmds.c: Update. * cli/cli-interp.c: Update. * cli/cli-script.c: Update. * common/common-exceptions.c: Update. * common/new-op.c: Update. * common/selftest.c: Update. * compile/compile-c-symbols.c: Update. * compile/compile-cplus-symbols.c: Update. * compile/compile-object-load.c: Update. * compile/compile-object-run.c: Update. * completer.c: Update. * corelow.c: Update. * cp-abi.c: Update. * cp-support.c: Update. * cp-valprint.c: Update. * darwin-nat.c: Update. * disasm-selftests.c: Update. * dtrace-probe.c: Update. * dwarf-index-cache.c: Update. * dwarf-index-write.c: Update. * dwarf2-frame-tailcall.c: Update. * dwarf2-frame.c: Update. * dwarf2loc.c: Update. * dwarf2read.c: Update. * eval.c: Update. * event-loop.c: Update. * event-top.c: Update. * exec.c: Update. * f-valprint.c: Update. * fbsd-tdep.c: Update. * frame-unwind.c: Update. * frame.c: Update. * gdbtypes.c: Update. * gnu-v3-abi.c: Update. * guile/guile-internal.h: Update. * guile/scm-block.c: Update. * guile/scm-breakpoint.c: Update. * guile/scm-cmd.c: Update. * guile/scm-disasm.c: Update. * guile/scm-frame.c: Update. * guile/scm-lazy-string.c: Update. * guile/scm-math.c: Update. * guile/scm-param.c: Update. * guile/scm-ports.c: Update. * guile/scm-pretty-print.c: Update. * guile/scm-symbol.c: Update. * guile/scm-symtab.c: Update. * guile/scm-type.c: Update. * guile/scm-value.c: Update. * i386-linux-tdep.c: Update. * i386-tdep.c: Update. * inf-loop.c: Update. * infcall.c: Update. * infcmd.c: Update. * infrun.c: Update. * jit.c: Update. * language.c: Update. * linespec.c: Update. * linux-fork.c: Update. * linux-nat.c: Update. * linux-tdep.c: Update. * linux-thread-db.c: Update. * main.c: Update. * mi/mi-cmd-break.c: Update. * mi/mi-cmd-stack.c: Update. * mi/mi-interp.c: Update. * mi/mi-main.c: Update. * objc-lang.c: Update. * p-valprint.c: Update. * parse.c: Update. * ppc-linux-tdep.c: Update. * printcmd.c: Update. * python/py-arch.c: Update. * python/py-breakpoint.c: Update. * python/py-cmd.c: Update. * python/py-finishbreakpoint.c: Update. * python/py-frame.c: Update. * python/py-framefilter.c: Update. * python/py-gdb-readline.c: Update. * python/py-inferior.c: Update. * python/py-infthread.c: Update. * python/py-lazy-string.c: Update. * python/py-linetable.c: Update. * python/py-objfile.c: Update. * python/py-param.c: Update. * python/py-prettyprint.c: Update. * python/py-progspace.c: Update. * python/py-record-btrace.c: Update. * python/py-record.c: Update. * python/py-symbol.c: Update. * python/py-type.c: Update. * python/py-unwind.c: Update. * python/py-utils.c: Update. * python/py-value.c: Update. * python/python.c: Update. * record-btrace.c: Update. * record-full.c: Update. * remote-fileio.c: Update. * remote.c: Update. * riscv-tdep.c: Update. * rs6000-aix-tdep.c: Update. * rs6000-tdep.c: Update. * rust-exp.y: Update. * rust-lang.c: Update. * s390-tdep.c: Update. * selftest-arch.c: Update. * solib-dsbt.c: Update. * solib-frv.c: Update. * solib-spu.c: Update. * solib-svr4.c: Update. * solib.c: Update. * sparc64-linux-tdep.c: Update. * stack.c: Update. * symfile-mem.c: Update. * symmisc.c: Update. * target.c: Update. * thread.c: Update. * top.c: Update. * tracefile-tfile.c: Update. * tui/tui.c: Update. * typeprint.c: Update. * unittests/cli-utils-selftests.c: Update. * unittests/parse-connection-spec-selftests.c: Update. * valops.c: Update. * valprint.c: Update. * value.c: Update. * varobj.c: Update. * windows-nat.c: Update. * x86-linux-nat.c: Update. * xml-support.c: Update. gdb/gdbserver/ChangeLog 2019-04-08 Tom Tromey <tom@tromey.com> * gdbreplay.c: Update. * linux-low.c: Update. * server.c: Update.
2019-04-04 05:59:07 +08:00
catch (const gdb_exception_error &except)
Split TRY_CATCH into TRY + CATCH This patch splits the TRY_CATCH macro into three, so that we go from this: ~~~ volatile gdb_exception ex; TRY_CATCH (ex, RETURN_MASK_ERROR) { } if (ex.reason < 0) { } ~~~ to this: ~~~ TRY { } CATCH (ex, RETURN_MASK_ERROR) { } END_CATCH ~~~ Thus, we'll be getting rid of the local volatile exception object, and declaring the caught exception in the catch block. This allows reimplementing TRY/CATCH in terms of C++ exceptions when building in C++ mode, while still allowing to build GDB in C mode (using setjmp/longjmp), as a transition step. TBC, after this patch, is it _not_ valid to have code between the TRY and the CATCH blocks, like: TRY { } // some code here. CATCH (ex, RETURN_MASK_ERROR) { } END_CATCH Just like it isn't valid to do that with C++'s native try/catch. By switching to creating the exception object inside the CATCH block scope, we can get rid of all the explicitly allocated volatile exception objects all over the tree, and map the CATCH block more directly to C++'s catch blocks. The majority of the TRY_CATCH -> TRY+CATCH+END_CATCH conversion was done with a script, rerun from scratch at every rebase, no manual editing involved. After the mechanical conversion, a few places needed manual intervention, to fix preexisting cases where we were using the exception object outside of the TRY_CATCH block, and cases where we were using "else" after a 'if (ex.reason) < 0)' [a CATCH after this patch]. The result was folded into this patch so that GDB still builds at each incremental step. END_CATCH is necessary for two reasons: First, because we name the exception object in the CATCH block, which requires creating a scope, which in turn must be closed somewhere. Declaring the exception variable in the initializer field of a for block, like: #define CATCH(EXCEPTION, mask) \ for (struct gdb_exception EXCEPTION; \ exceptions_state_mc_catch (&EXCEPTION, MASK); \ EXCEPTION = exception_none) would avoid needing END_CATCH, but alas, in C mode, we build with C90, which doesn't allow mixed declarations and code. Second, because when TRY/CATCH are wired to real C++ try/catch, as long as we need to handle cleanup chains, even if there's no CATCH block that wants to catch the exception, we need for stop at every frame in the unwind chain and run cleanups, then rethrow. That will be done in END_CATCH. After we require C++, we'll still need TRY/CATCH/END_CATCH until cleanups are completely phased out -- TRY/CATCH in C++ mode will save/restore the current cleanup chain, like in C mode, and END_CATCH catches otherwise uncaugh exceptions, runs cleanups and rethrows, so that C++ cleanups and exceptions can coexist. IMO, this still makes the TRY/CATCH code look a bit more like a newcomer would expect, so IMO worth it even if we weren't considering C++. gdb/ChangeLog. 2015-03-07 Pedro Alves <palves@redhat.com> * common/common-exceptions.c (struct catcher) <exception>: No longer a pointer to volatile exception. Now an exception value. <mask>: Delete field. (exceptions_state_mc_init): Remove all parameters. Adjust. (exceptions_state_mc): No longer pop the catcher here. (exceptions_state_mc_catch): New function. (throw_exception): Adjust. * common/common-exceptions.h (exceptions_state_mc_init): Remove all parameters. (exceptions_state_mc_catch): Declare. (TRY_CATCH): Rename to ... (TRY): ... this. Remove EXCEPTION and MASK parameters. (CATCH, END_CATCH): New. All callers adjusted. gdb/gdbserver/ChangeLog: 2015-03-07 Pedro Alves <palves@redhat.com> Adjust all callers of TRY_CATCH to use TRY/CATCH/END_CATCH instead.
2015-03-07 23:14:14 +08:00
{
}
}
}
2010-07-07 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> Support for hw accelerated condition watchpoints in booke powerpc. * breakpoint.c (fetch_watchpoint_value): Rename to fetch_subexp_value and move to eval.c. Change callers. (insert_bp_location): Pass watchpoint condition in target_insert_watchpoint. (remove_breakpoint_1) Pass watchpoint condition in target_remove_watchpoint. (watchpoint_locations_match): Call target_can_accel_watchpoint_condition. * eval.c: Include wrapper.h. (fetch_subexp_value): Moved from breakpoint.c. * ppc-linux-nat.c (ppc_linux_region_ok_for_hw_watchpoint): Formatting fix. (can_use_watchpoint_cond_accel): New function. (calculate_dvc): Likewise. (num_memory_accesses): Likewise. (check_condition): Likewise. (ppc_linux_can_accel_watchpoint_condition): Likewise (ppc_linux_insert_watchpoint): Call can_use_watchpoint_cond_accel, check_condition and calculate_dvc. (ppc_linux_remove_watchpoint): Likewise. (_initialize_ppc_linux_nat): Set to_can_accel_watchpoint_condition to ppc_linux_can_accel_watchpoint_condition * target.c (debug_to_insert_watchpoint): Add argument for watchpoint condition. (debug_to_remove_watchpoint): Likewise. (debug_to_can_accel_watchpoint_condition): New function. (update_current_target): Set to_can_accel_watchpoint_condition. (setup_target_debug): Set to_can_accel_watchpoint_condition. * target.h: Add opaque declaration for struct expression. (struct target_ops) <to_insert_watchpoint>, <to_remove_watchpoint>: Add new arguments to pass the watchpoint <to_can_accel_watchpoint_condition>: New member. condition. Update all callers and implementations. (target_can_accel_watchpoint_condition): New macro. * value.c (free_value_chain): New function. * value.h (fetch_subexp_value): New prototype. (free_value_chain): Likewise.
2010-07-08 00:15:18 +08:00
if (val_chain)
{
/* Return the chain of intermediate values. We use this to
decide which addresses to watch. */
*val_chain = value_release_to_mark (mark);
2010-07-07 Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com> Thiago Jung Bauermann <bauerman@br.ibm.com> Support for hw accelerated condition watchpoints in booke powerpc. * breakpoint.c (fetch_watchpoint_value): Rename to fetch_subexp_value and move to eval.c. Change callers. (insert_bp_location): Pass watchpoint condition in target_insert_watchpoint. (remove_breakpoint_1) Pass watchpoint condition in target_remove_watchpoint. (watchpoint_locations_match): Call target_can_accel_watchpoint_condition. * eval.c: Include wrapper.h. (fetch_subexp_value): Moved from breakpoint.c. * ppc-linux-nat.c (ppc_linux_region_ok_for_hw_watchpoint): Formatting fix. (can_use_watchpoint_cond_accel): New function. (calculate_dvc): Likewise. (num_memory_accesses): Likewise. (check_condition): Likewise. (ppc_linux_can_accel_watchpoint_condition): Likewise (ppc_linux_insert_watchpoint): Call can_use_watchpoint_cond_accel, check_condition and calculate_dvc. (ppc_linux_remove_watchpoint): Likewise. (_initialize_ppc_linux_nat): Set to_can_accel_watchpoint_condition to ppc_linux_can_accel_watchpoint_condition * target.c (debug_to_insert_watchpoint): Add argument for watchpoint condition. (debug_to_remove_watchpoint): Likewise. (debug_to_can_accel_watchpoint_condition): New function. (update_current_target): Set to_can_accel_watchpoint_condition. (setup_target_debug): Set to_can_accel_watchpoint_condition. * target.h: Add opaque declaration for struct expression. (struct target_ops) <to_insert_watchpoint>, <to_remove_watchpoint>: Add new arguments to pass the watchpoint <to_can_accel_watchpoint_condition>: New member. condition. Update all callers and implementations. (target_can_accel_watchpoint_condition): New macro. * value.c (free_value_chain): New function. * value.h (fetch_subexp_value): New prototype. (free_value_chain): Likewise.
2010-07-08 00:15:18 +08:00
}
}
/* Promote value ARG1 as appropriate before performing a unary operation
on this argument.
If the result is not appropriate for any particular language then it
needs to patch this function. */
void
unop_promote (const struct language_defn *language, struct gdbarch *gdbarch,
struct value **arg1)
{
struct type *type1;
*arg1 = coerce_ref (*arg1);
type1 = check_typedef ((*arg1)->type ());
if (is_integral_type (type1))
{
switch (language->la_language)
{
default:
/* Perform integral promotion for ANSI C/C++.
[gdb] Fix more typos in comments Fix typos in comments. NFC. Tested on x86_64-linux. gdb/ChangeLog: 2019-10-18 Tom de Vries <tdevries@suse.de> * aarch64-tdep.c: Fix typos in comments. * ada-lang.c: Same. * ada-tasks.c: Same. * alpha-tdep.c: Same. * alpha-tdep.h: Same. * amd64-nat.c: Same. * amd64-windows-tdep.c: Same. * arc-tdep.c: Same. * arc-tdep.h: Same. * arch-utils.c: Same. * arm-nbsd-tdep.c: Same. * arm-tdep.c: Same. * ax-gdb.c: Same. * blockframe.c: Same. * btrace.c: Same. * c-varobj.c: Same. * coff-pe-read.c: Same. * coffread.c: Same. * cris-tdep.c: Same. * darwin-nat.c: Same. * dbxread.c: Same. * dcache.c: Same. * disasm.c: Same. * dtrace-probe.c: Same. * dwarf-index-write.c: Same. * dwarf2-frame-tailcall.c: Same. * dwarf2-frame.c: Same. * dwarf2read.c: Same. * eval.c: Same. * exceptions.c: Same. * fbsd-tdep.c: Same. * findvar.c: Same. * frame.c: Same. * frv-tdep.c: Same. * gnu-v3-abi.c: Same. * go32-nat.c: Same. * h8300-tdep.c: Same. * hppa-tdep.c: Same. * i386-linux-tdep.c: Same. * i386-tdep.c: Same. * ia64-libunwind-tdep.c: Same. * ia64-tdep.c: Same. * infcmd.c: Same. * infrun.c: Same. * linespec.c: Same. * linux-nat.c: Same. * linux-thread-db.c: Same. * machoread.c: Same. * mdebugread.c: Same. * mep-tdep.c: Same. * mn10300-tdep.c: Same. * namespace.c: Same. * objfiles.c: Same. * opencl-lang.c: Same. * or1k-tdep.c: Same. * osabi.c: Same. * ppc-linux-nat.c: Same. * ppc-linux-tdep.c: Same. * ppc-sysv-tdep.c: Same. * printcmd.c: Same. * procfs.c: Same. * record-btrace.c: Same. * record-full.c: Same. * remote-fileio.c: Same. * remote.c: Same. * rs6000-tdep.c: Same. * s12z-tdep.c: Same. * score-tdep.c: Same. * ser-base.c: Same. * ser-go32.c: Same. * skip.c: Same. * sol-thread.c: Same. * solib-svr4.c: Same. * solib.c: Same. * source.c: Same. * sparc-nat.c: Same. * sparc-sol2-tdep.c: Same. * sparc-tdep.c: Same. * sparc64-tdep.c: Same. * stabsread.c: Same. * stack.c: Same. * symfile.c: Same. * symtab.c: Same. * target-descriptions.c: Same. * target-float.c: Same. * thread.c: Same. * utils.c: Same. * valops.c: Same. * valprint.c: Same. * value.c: Same. * varobj.c: Same. * windows-nat.c: Same. * xcoffread.c: Same. * xstormy16-tdep.c: Same. * xtensa-tdep.c: Same. Change-Id: I5175f1b107bfa4e1cdd4a3361ccb4739e53c75c4
2019-10-18 08:48:08 +08:00
If not appropriate for any particular language
it needs to modify this function. */
{
struct type *builtin_int = builtin_type (gdbarch)->builtin_int;
if (type1->length () < builtin_int->length ())
*arg1 = value_cast (builtin_int, *arg1);
}
break;
}
}
}
/* Promote values ARG1 and ARG2 as appropriate before performing a binary
operation on those two operands.
If the result is not appropriate for any particular language then it
needs to patch this function. */
void
binop_promote (const struct language_defn *language, struct gdbarch *gdbarch,
struct value **arg1, struct value **arg2)
{
struct type *promoted_type = NULL;
struct type *type1;
struct type *type2;
*arg1 = coerce_ref (*arg1);
*arg2 = coerce_ref (*arg2);
type1 = check_typedef ((*arg1)->type ());
type2 = check_typedef ((*arg2)->type ());
if ((type1->code () != TYPE_CODE_FLT
&& type1->code () != TYPE_CODE_DECFLOAT
&& !is_integral_type (type1))
|| (type2->code () != TYPE_CODE_FLT
&& type2->code () != TYPE_CODE_DECFLOAT
&& !is_integral_type (type2)))
return;
if (is_fixed_point_type (type1) || is_fixed_point_type (type2))
return;
if (type1->code () == TYPE_CODE_DECFLOAT
|| type2->code () == TYPE_CODE_DECFLOAT)
{
/* No promotion required. */
}
else if (type1->code () == TYPE_CODE_FLT
|| type2->code () == TYPE_CODE_FLT)
{
switch (language->la_language)
{
case language_c:
case language_cplus:
case language_asm:
case language_objc:
case language_opencl:
/* No promotion required. */
break;
default:
/* For other languages the result type is unchanged from gdb
version 6.7 for backward compatibility.
If either arg was long double, make sure that value is also long
double. Otherwise use double. */
if (type1->length () * 8 > gdbarch_double_bit (gdbarch)
|| type2->length () * 8 > gdbarch_double_bit (gdbarch))
promoted_type = builtin_type (gdbarch)->builtin_long_double;
else
promoted_type = builtin_type (gdbarch)->builtin_double;
break;
}
}
else if (type1->code () == TYPE_CODE_BOOL
&& type2->code () == TYPE_CODE_BOOL)
{
/* No promotion required. */
}
else
/* Integral operations here. */
/* FIXME: Also mixed integral/booleans, with result an integer. */
{
const struct builtin_type *builtin = builtin_type (gdbarch);
unsigned int promoted_len1 = type1->length ();
unsigned int promoted_len2 = type2->length ();
int is_unsigned1 = type1->is_unsigned ();
int is_unsigned2 = type2->is_unsigned ();
unsigned int result_len;
int unsigned_operation;
/* Determine type length and signedness after promotion for
gdb, gdbserver, gdbsupport: fix leading space vs tabs issues Many spots incorrectly use only spaces for indentation (for example, there are a lot of spots in ada-lang.c). I've always found it awkward when I needed to edit one of these spots: do I keep the original wrong indentation, or do I fix it? What if the lines around it are also wrong, do I fix them too? I probably don't want to fix them in the same patch, to avoid adding noise to my patch. So I propose to fix as much as possible once and for all (hopefully). One typical counter argument for this is that it makes code archeology more difficult, because git-blame will show this commit as the last change for these lines. My counter counter argument is: when git-blaming, you often need to do "blame the file at the parent commit" anyway, to go past some other refactor that touched the line you are interested in, but is not the change you are looking for. So you already need a somewhat efficient way to do this. Using some interactive tool, rather than plain git-blame, makes this trivial. For example, I use "tig blame <file>", where going back past the commit that changed the currently selected line is one keystroke. It looks like Magit in Emacs does it too (though I've never used it). Web viewers of Github and Gitlab do it too. My point is that it won't really make archeology more difficult. The other typical counter argument is that it will cause conflicts with existing patches. That's true... but it's a one time cost, and those are not conflicts that are difficult to resolve. I have also tried "git rebase --ignore-whitespace", it seems to work well. Although that will re-introduce the faulty indentation, so one needs to take care of fixing the indentation in the patch after that (which is easy). gdb/ChangeLog: * aarch64-linux-tdep.c: Fix indentation. * aarch64-ravenscar-thread.c: Fix indentation. * aarch64-tdep.c: Fix indentation. * aarch64-tdep.h: Fix indentation. * ada-lang.c: Fix indentation. * ada-lang.h: Fix indentation. * ada-tasks.c: Fix indentation. * ada-typeprint.c: Fix indentation. * ada-valprint.c: Fix indentation. * ada-varobj.c: Fix indentation. * addrmap.c: Fix indentation. * addrmap.h: Fix indentation. * agent.c: Fix indentation. * aix-thread.c: Fix indentation. * alpha-bsd-nat.c: Fix indentation. * alpha-linux-tdep.c: Fix indentation. * alpha-mdebug-tdep.c: Fix indentation. * alpha-nbsd-tdep.c: Fix indentation. * alpha-obsd-tdep.c: Fix indentation. * alpha-tdep.c: Fix indentation. * amd64-bsd-nat.c: Fix indentation. * amd64-darwin-tdep.c: Fix indentation. * amd64-linux-nat.c: Fix indentation. * amd64-linux-tdep.c: Fix indentation. * amd64-nat.c: Fix indentation. * amd64-obsd-tdep.c: Fix indentation. * amd64-tdep.c: Fix indentation. * amd64-windows-tdep.c: Fix indentation. * annotate.c: Fix indentation. * arc-tdep.c: Fix indentation. * arch-utils.c: Fix indentation. * arch/arm-get-next-pcs.c: Fix indentation. * arch/arm.c: Fix indentation. * arm-linux-nat.c: Fix indentation. * arm-linux-tdep.c: Fix indentation. * arm-nbsd-tdep.c: Fix indentation. * arm-pikeos-tdep.c: Fix indentation. * arm-tdep.c: Fix indentation. * arm-tdep.h: Fix indentation. * arm-wince-tdep.c: Fix indentation. * auto-load.c: Fix indentation. * auxv.c: Fix indentation. * avr-tdep.c: Fix indentation. * ax-gdb.c: Fix indentation. * ax-general.c: Fix indentation. * bfin-linux-tdep.c: Fix indentation. * block.c: Fix indentation. * block.h: Fix indentation. * blockframe.c: Fix indentation. * bpf-tdep.c: Fix indentation. * break-catch-sig.c: Fix indentation. * break-catch-syscall.c: Fix indentation. * break-catch-throw.c: Fix indentation. * breakpoint.c: Fix indentation. * breakpoint.h: Fix indentation. * bsd-uthread.c: Fix indentation. * btrace.c: Fix indentation. * build-id.c: Fix indentation. * buildsym-legacy.h: Fix indentation. * buildsym.c: Fix indentation. * c-typeprint.c: Fix indentation. * c-valprint.c: Fix indentation. * c-varobj.c: Fix indentation. * charset.c: Fix indentation. * cli/cli-cmds.c: Fix indentation. * cli/cli-decode.c: Fix indentation. * cli/cli-decode.h: Fix indentation. * cli/cli-script.c: Fix indentation. * cli/cli-setshow.c: Fix indentation. * coff-pe-read.c: Fix indentation. * coffread.c: Fix indentation. * compile/compile-cplus-types.c: Fix indentation. * compile/compile-object-load.c: Fix indentation. * compile/compile-object-run.c: Fix indentation. * completer.c: Fix indentation. * corefile.c: Fix indentation. * corelow.c: Fix indentation. * cp-abi.h: Fix indentation. * cp-namespace.c: Fix indentation. * cp-support.c: Fix indentation. * cp-valprint.c: Fix indentation. * cris-linux-tdep.c: Fix indentation. * cris-tdep.c: Fix indentation. * darwin-nat-info.c: Fix indentation. * darwin-nat.c: Fix indentation. * darwin-nat.h: Fix indentation. * dbxread.c: Fix indentation. * dcache.c: Fix indentation. * disasm.c: Fix indentation. * dtrace-probe.c: Fix indentation. * dwarf2/abbrev.c: Fix indentation. * dwarf2/attribute.c: Fix indentation. * dwarf2/expr.c: Fix indentation. * dwarf2/frame.c: Fix indentation. * dwarf2/index-cache.c: Fix indentation. * dwarf2/index-write.c: Fix indentation. * dwarf2/line-header.c: Fix indentation. * dwarf2/loc.c: Fix indentation. * dwarf2/macro.c: Fix indentation. * dwarf2/read.c: Fix indentation. * dwarf2/read.h: Fix indentation. * elfread.c: Fix indentation. * eval.c: Fix indentation. * event-top.c: Fix indentation. * exec.c: Fix indentation. * exec.h: Fix indentation. * expprint.c: Fix indentation. * f-lang.c: Fix indentation. * f-typeprint.c: Fix indentation. * f-valprint.c: Fix indentation. * fbsd-nat.c: Fix indentation. * fbsd-tdep.c: Fix indentation. * findvar.c: Fix indentation. * fork-child.c: Fix indentation. * frame-unwind.c: Fix indentation. * frame-unwind.h: Fix indentation. * frame.c: Fix indentation. * frv-linux-tdep.c: Fix indentation. * frv-tdep.c: Fix indentation. * frv-tdep.h: Fix indentation. * ft32-tdep.c: Fix indentation. * gcore.c: Fix indentation. * gdb_bfd.c: Fix indentation. * gdbarch.sh: Fix indentation. * gdbarch.c: Re-generate * gdbarch.h: Re-generate. * gdbcore.h: Fix indentation. * gdbthread.h: Fix indentation. * gdbtypes.c: Fix indentation. * gdbtypes.h: Fix indentation. * glibc-tdep.c: Fix indentation. * gnu-nat.c: Fix indentation. * gnu-nat.h: Fix indentation. * gnu-v2-abi.c: Fix indentation. * gnu-v3-abi.c: Fix indentation. * go32-nat.c: Fix indentation. * guile/guile-internal.h: Fix indentation. * guile/scm-cmd.c: Fix indentation. * guile/scm-frame.c: Fix indentation. * guile/scm-iterator.c: Fix indentation. * guile/scm-math.c: Fix indentation. * guile/scm-ports.c: Fix indentation. * guile/scm-pretty-print.c: Fix indentation. * guile/scm-value.c: Fix indentation. * h8300-tdep.c: Fix indentation. * hppa-linux-nat.c: Fix indentation. * hppa-linux-tdep.c: Fix indentation. * hppa-nbsd-nat.c: Fix indentation. * hppa-nbsd-tdep.c: Fix indentation. * hppa-obsd-nat.c: Fix indentation. * hppa-tdep.c: Fix indentation. * hppa-tdep.h: Fix indentation. * i386-bsd-nat.c: Fix indentation. * i386-darwin-nat.c: Fix indentation. * i386-darwin-tdep.c: Fix indentation. * i386-dicos-tdep.c: Fix indentation. * i386-gnu-nat.c: Fix indentation. * i386-linux-nat.c: Fix indentation. * i386-linux-tdep.c: Fix indentation. * i386-nto-tdep.c: Fix indentation. * i386-obsd-tdep.c: Fix indentation. * i386-sol2-nat.c: Fix indentation. * i386-tdep.c: Fix indentation. * i386-tdep.h: Fix indentation. * i386-windows-tdep.c: Fix indentation. * i387-tdep.c: Fix indentation. * i387-tdep.h: Fix indentation. * ia64-libunwind-tdep.c: Fix indentation. * ia64-libunwind-tdep.h: Fix indentation. * ia64-linux-nat.c: Fix indentation. * ia64-linux-tdep.c: Fix indentation. * ia64-tdep.c: Fix indentation. * ia64-tdep.h: Fix indentation. * ia64-vms-tdep.c: Fix indentation. * infcall.c: Fix indentation. * infcmd.c: Fix indentation. * inferior.c: Fix indentation. * infrun.c: Fix indentation. * iq2000-tdep.c: Fix indentation. * language.c: Fix indentation. * linespec.c: Fix indentation. * linux-fork.c: Fix indentation. * linux-nat.c: Fix indentation. * linux-tdep.c: Fix indentation. * linux-thread-db.c: Fix indentation. * lm32-tdep.c: Fix indentation. * m2-lang.c: Fix indentation. * m2-typeprint.c: Fix indentation. * m2-valprint.c: Fix indentation. * m32c-tdep.c: Fix indentation. * m32r-linux-tdep.c: Fix indentation. * m32r-tdep.c: Fix indentation. * m68hc11-tdep.c: Fix indentation. * m68k-bsd-nat.c: Fix indentation. * m68k-linux-nat.c: Fix indentation. * m68k-linux-tdep.c: Fix indentation. * m68k-tdep.c: Fix indentation. * machoread.c: Fix indentation. * macrocmd.c: Fix indentation. * macroexp.c: Fix indentation. * macroscope.c: Fix indentation. * macrotab.c: Fix indentation. * macrotab.h: Fix indentation. * main.c: Fix indentation. * mdebugread.c: Fix indentation. * mep-tdep.c: Fix indentation. * mi/mi-cmd-catch.c: Fix indentation. * mi/mi-cmd-disas.c: Fix indentation. * mi/mi-cmd-env.c: Fix indentation. * mi/mi-cmd-stack.c: Fix indentation. * mi/mi-cmd-var.c: Fix indentation. * mi/mi-cmds.c: Fix indentation. * mi/mi-main.c: Fix indentation. * mi/mi-parse.c: Fix indentation. * microblaze-tdep.c: Fix indentation. * minidebug.c: Fix indentation. * minsyms.c: Fix indentation. * mips-linux-nat.c: Fix indentation. * mips-linux-tdep.c: Fix indentation. * mips-nbsd-tdep.c: Fix indentation. * mips-tdep.c: Fix indentation. * mn10300-linux-tdep.c: Fix indentation. * mn10300-tdep.c: Fix indentation. * moxie-tdep.c: Fix indentation. * msp430-tdep.c: Fix indentation. * namespace.h: Fix indentation. * nat/fork-inferior.c: Fix indentation. * nat/gdb_ptrace.h: Fix indentation. * nat/linux-namespaces.c: Fix indentation. * nat/linux-osdata.c: Fix indentation. * nat/netbsd-nat.c: Fix indentation. * nat/x86-dregs.c: Fix indentation. * nbsd-nat.c: Fix indentation. * nbsd-tdep.c: Fix indentation. * nios2-linux-tdep.c: Fix indentation. * nios2-tdep.c: Fix indentation. * nto-procfs.c: Fix indentation. * nto-tdep.c: Fix indentation. * objfiles.c: Fix indentation. * objfiles.h: Fix indentation. * opencl-lang.c: Fix indentation. * or1k-tdep.c: Fix indentation. * osabi.c: Fix indentation. * osabi.h: Fix indentation. * osdata.c: Fix indentation. * p-lang.c: Fix indentation. * p-typeprint.c: Fix indentation. * p-valprint.c: Fix indentation. * parse.c: Fix indentation. * ppc-linux-nat.c: Fix indentation. * ppc-linux-tdep.c: Fix indentation. * ppc-nbsd-nat.c: Fix indentation. * ppc-nbsd-tdep.c: Fix indentation. * ppc-obsd-nat.c: Fix indentation. * ppc-ravenscar-thread.c: Fix indentation. * ppc-sysv-tdep.c: Fix indentation. * ppc64-tdep.c: Fix indentation. * printcmd.c: Fix indentation. * proc-api.c: Fix indentation. * producer.c: Fix indentation. * producer.h: Fix indentation. * prologue-value.c: Fix indentation. * prologue-value.h: Fix indentation. * psymtab.c: Fix indentation. * python/py-arch.c: Fix indentation. * python/py-bpevent.c: Fix indentation. * python/py-event.c: Fix indentation. * python/py-event.h: Fix indentation. * python/py-finishbreakpoint.c: Fix indentation. * python/py-frame.c: Fix indentation. * python/py-framefilter.c: Fix indentation. * python/py-inferior.c: Fix indentation. * python/py-infthread.c: Fix indentation. * python/py-objfile.c: Fix indentation. * python/py-prettyprint.c: Fix indentation. * python/py-registers.c: Fix indentation. * python/py-signalevent.c: Fix indentation. * python/py-stopevent.c: Fix indentation. * python/py-stopevent.h: Fix indentation. * python/py-threadevent.c: Fix indentation. * python/py-tui.c: Fix indentation. * python/py-unwind.c: Fix indentation. * python/py-value.c: Fix indentation. * python/py-xmethods.c: Fix indentation. * python/python-internal.h: Fix indentation. * python/python.c: Fix indentation. * ravenscar-thread.c: Fix indentation. * record-btrace.c: Fix indentation. * record-full.c: Fix indentation. * record.c: Fix indentation. * reggroups.c: Fix indentation. * regset.h: Fix indentation. * remote-fileio.c: Fix indentation. * remote.c: Fix indentation. * reverse.c: Fix indentation. * riscv-linux-tdep.c: Fix indentation. * riscv-ravenscar-thread.c: Fix indentation. * riscv-tdep.c: Fix indentation. * rl78-tdep.c: Fix indentation. * rs6000-aix-tdep.c: Fix indentation. * rs6000-lynx178-tdep.c: Fix indentation. * rs6000-nat.c: Fix indentation. * rs6000-tdep.c: Fix indentation. * rust-lang.c: Fix indentation. * rx-tdep.c: Fix indentation. * s12z-tdep.c: Fix indentation. * s390-linux-tdep.c: Fix indentation. * score-tdep.c: Fix indentation. * ser-base.c: Fix indentation. * ser-mingw.c: Fix indentation. * ser-uds.c: Fix indentation. * ser-unix.c: Fix indentation. * serial.c: Fix indentation. * sh-linux-tdep.c: Fix indentation. * sh-nbsd-tdep.c: Fix indentation. * sh-tdep.c: Fix indentation. * skip.c: Fix indentation. * sol-thread.c: Fix indentation. * solib-aix.c: Fix indentation. * solib-darwin.c: Fix indentation. * solib-frv.c: Fix indentation. * solib-svr4.c: Fix indentation. * solib.c: Fix indentation. * source.c: Fix indentation. * sparc-linux-tdep.c: Fix indentation. * sparc-nbsd-tdep.c: Fix indentation. * sparc-obsd-tdep.c: Fix indentation. * sparc-ravenscar-thread.c: Fix indentation. * sparc-tdep.c: Fix indentation. * sparc64-linux-tdep.c: Fix indentation. * sparc64-nbsd-tdep.c: Fix indentation. * sparc64-obsd-tdep.c: Fix indentation. * sparc64-tdep.c: Fix indentation. * stabsread.c: Fix indentation. * stack.c: Fix indentation. * stap-probe.c: Fix indentation. * stubs/ia64vms-stub.c: Fix indentation. * stubs/m32r-stub.c: Fix indentation. * stubs/m68k-stub.c: Fix indentation. * stubs/sh-stub.c: Fix indentation. * stubs/sparc-stub.c: Fix indentation. * symfile-mem.c: Fix indentation. * symfile.c: Fix indentation. * symfile.h: Fix indentation. * symmisc.c: Fix indentation. * symtab.c: Fix indentation. * symtab.h: Fix indentation. * target-float.c: Fix indentation. * target.c: Fix indentation. * target.h: Fix indentation. * tic6x-tdep.c: Fix indentation. * tilegx-linux-tdep.c: Fix indentation. * tilegx-tdep.c: Fix indentation. * top.c: Fix indentation. * tracefile-tfile.c: Fix indentation. * tracepoint.c: Fix indentation. * tui/tui-disasm.c: Fix indentation. * tui/tui-io.c: Fix indentation. * tui/tui-regs.c: Fix indentation. * tui/tui-stack.c: Fix indentation. * tui/tui-win.c: Fix indentation. * tui/tui-winsource.c: Fix indentation. * tui/tui.c: Fix indentation. * typeprint.c: Fix indentation. * ui-out.h: Fix indentation. * unittests/copy_bitwise-selftests.c: Fix indentation. * unittests/memory-map-selftests.c: Fix indentation. * utils.c: Fix indentation. * v850-tdep.c: Fix indentation. * valarith.c: Fix indentation. * valops.c: Fix indentation. * valprint.c: Fix indentation. * valprint.h: Fix indentation. * value.c: Fix indentation. * value.h: Fix indentation. * varobj.c: Fix indentation. * vax-tdep.c: Fix indentation. * windows-nat.c: Fix indentation. * windows-tdep.c: Fix indentation. * xcoffread.c: Fix indentation. * xml-syscall.c: Fix indentation. * xml-tdesc.c: Fix indentation. * xstormy16-tdep.c: Fix indentation. * xtensa-config.c: Fix indentation. * xtensa-linux-nat.c: Fix indentation. * xtensa-linux-tdep.c: Fix indentation. * xtensa-tdep.c: Fix indentation. gdbserver/ChangeLog: * ax.cc: Fix indentation. * dll.cc: Fix indentation. * inferiors.h: Fix indentation. * linux-low.cc: Fix indentation. * linux-nios2-low.cc: Fix indentation. * linux-ppc-ipa.cc: Fix indentation. * linux-ppc-low.cc: Fix indentation. * linux-x86-low.cc: Fix indentation. * linux-xtensa-low.cc: Fix indentation. * regcache.cc: Fix indentation. * server.cc: Fix indentation. * tracepoint.cc: Fix indentation. gdbsupport/ChangeLog: * common-exceptions.h: Fix indentation. * event-loop.cc: Fix indentation. * fileio.cc: Fix indentation. * filestuff.cc: Fix indentation. * gdb-dlfcn.cc: Fix indentation. * gdb_string_view.h: Fix indentation. * job-control.cc: Fix indentation. * signals.cc: Fix indentation. Change-Id: I4bad7ae6be0fbe14168b8ebafb98ffe14964a695
2020-11-02 23:26:14 +08:00
both operands. */
if (promoted_len1 < builtin->builtin_int->length ())
{
is_unsigned1 = 0;
promoted_len1 = builtin->builtin_int->length ();
}
if (promoted_len2 < builtin->builtin_int->length ())
{
is_unsigned2 = 0;
promoted_len2 = builtin->builtin_int->length ();
}
if (promoted_len1 > promoted_len2)
{
unsigned_operation = is_unsigned1;
result_len = promoted_len1;
}
else if (promoted_len2 > promoted_len1)
{
unsigned_operation = is_unsigned2;
result_len = promoted_len2;
}
else
{
unsigned_operation = is_unsigned1 || is_unsigned2;
result_len = promoted_len1;
}
switch (language->la_language)
{
case language_opencl:
if (result_len
<= lookup_signed_typename (language, "int")->length())
{
promoted_type =
(unsigned_operation
? lookup_unsigned_typename (language, "int")
: lookup_signed_typename (language, "int"));
}
else if (result_len
<= lookup_signed_typename (language, "long")->length())
{
promoted_type =
(unsigned_operation
? lookup_unsigned_typename (language, "long")
: lookup_signed_typename (language,"long"));
}
break;
default:
if (result_len <= builtin->builtin_int->length ())
{
promoted_type = (unsigned_operation
? builtin->builtin_unsigned_int
: builtin->builtin_int);
}
else if (result_len <= builtin->builtin_long->length ())
{
promoted_type = (unsigned_operation
? builtin->builtin_unsigned_long
: builtin->builtin_long);
}
else if (result_len <= builtin->builtin_long_long->length ())
{
promoted_type = (unsigned_operation
? builtin->builtin_unsigned_long_long
: builtin->builtin_long_long);
}
else
{
promoted_type = (unsigned_operation
? builtin->builtin_uint128
: builtin->builtin_int128);
}
break;
}
}
if (promoted_type)
{
/* Promote both operands to common type. */
*arg1 = value_cast (promoted_type, *arg1);
*arg2 = value_cast (promoted_type, *arg2);
}
}
static int
ptrmath_type_p (const struct language_defn *lang, struct type *type)
{
type = check_typedef (type);
Convert lvalue reference type check to general reference type check In almost all contexts (except for overload resolution rules and expression semantics), lvalue and rvalue references are equivalent. That means that in all but these cases we can replace a TYPE_CODE_REF check to a TYPE_IS_REFERENCE check and, for switch statements, add a case label for a rvalue reference type next to a case label for an lvalue reference type. This patch does exactly that. gdb/ChangeLog PR gdb/14441 * aarch64-tdep.c (aarch64_type_align) (aarch64_extract_return_value, aarch64_store_return_value): Change lvalue reference type checks to general reference type checks. * amd64-tdep.c (amd64_classify): Likewise. * amd64-windows-tdep.c (amd64_windows_passed_by_integer_register): Likewise. * arm-tdep.c (arm_type_align, arm_extract_return_value) (arm_store_return_value): Likewise. * ax-gdb.c (gen_fetch, gen_cast): Likewise. * c-typeprint.c (c_print_type): Likewise. * c-varobj.c (adjust_value_for_child_access, c_value_of_variable) (cplus_number_of_children, cplus_describe_child): Likewise. * compile/compile-c-symbols.c (generate_vla_size): Likewise. * completer.c (expression_completer): Likewise. * cp-support.c (make_symbol_overload_list_adl_namespace): Likewise. * darwin-nat-info.c (info_mach_region_command): Likewise. * dwarf2loc.c (entry_data_value_coerce_ref) (value_of_dwarf_reg_entry): Likewise. * eval.c (ptrmath_type_p, evaluate_subexp_standard) (evaluate_subexp_for_address, evaluate_subexp_for_sizeof): Likewise. * findvar.c (extract_typed_address, store_typed_address): Likewise. * gdbtypes.c (rank_one_type): Likewise. * hppa-tdep.c (hppa64_integral_or_pointer_p): Likewise. * infcall.c (value_arg_coerce): Likewise. * language.c (pointer_type): Likewise. * m32c-tdep.c (m32c_reg_arg_type, m32c_m16c_address_to_pointer): Likewise. * m88k-tdep.c (m88k_integral_or_pointer_p): Likewise. * mn10300-tdep.c (mn10300_type_align): Likewise. * msp430-tdep.c (msp430_push_dummy_call): Likewise. * ppc-sysv-tdep.c (do_ppc_sysv_return_value) (ppc64_sysv_abi_push_param, ppc64_sysv_abi_return_value): Likewise. * printcmd.c (print_formatted, x_command): Likewise. * python/py-type.c (typy_get_composite, typy_template_argument): Likewise. * python/py-value.c (valpy_referenced_value) (valpy_get_dynamic_type, value_has_field): Likewise. * s390-linux-tdep.c (s390_function_arg_integer): Likewise. * sparc-tdep.c (sparc_integral_or_pointer_p): Likewise. * sparc64-tdep.c (sparc64_integral_or_pointer_p): Likewise. * spu-tdep.c (spu_scalar_value_p): Likewise. * symtab.c (lookup_symbol_aux): Likewise. * typeprint.c (whatis_exp, print_type_scalar): Likewise. * valarith.c (binop_types_user_defined_p, unop_user_defined_p): Likewise. * valops.c (value_cast_pointers, value_cast) (value_reinterpret_cast, value_dynamic_cast, value_addr, typecmp) (value_struct_elt, value_struct_elt_bitpos) (value_find_oload_method_list, find_overload_match) (value_rtti_indirect_type): Likewise. * valprint.c (val_print_scalar_type_p, generic_val_print): Likewise. * value.c (value_actual_type, value_as_address, unpack_long) (pack_long, pack_unsigned_long, coerce_ref_if_computed) (coerce_ref): Likewise. * varobj.c (varobj_get_value_type): Likewise.
2017-03-21 04:47:54 +08:00
if (TYPE_IS_REFERENCE (type))
type = type->target_type ();
switch (type->code ())
{
case TYPE_CODE_PTR:
case TYPE_CODE_FUNC:
return 1;
case TYPE_CODE_ARRAY:
gdb: Convert language_data::c_style_arrays to a method Convert language_data::c_style_arrays member variable to a virtual method language_defn::c_style_arrays_p. There should be no user visible changes after this commit. gdb/ChangeLog: * ada-lang.c (ada_language_data): Remove c_style_arrays initializer. (ada_language::c_style_arrays_p): New member fuction. * c-lang.c (c_language_data): Remove c_style_arrays initializer. (cplus_language_data): Likewise. (asm_language_data): Likewise. (minimal_language_data): Likewise. * d-lang.c (d_language_data): Likewise. * eval.c (ptrmath_type_p): Update call to c_style_arrays_p. * f-lang.c (f_language_data): Remove c_style_arrays initializer. (f_language::c_style_arrays_p): New member function. * go-lang.c (go_language_data): Remove c_style_arrays initializer. * infcall.c (value_arg_coerce): Update call to c_style_arrays_p. * language.c (unknown_language_data): Remove c_style_arrays initializer. (auto_language_data): Likewise. * language.h (language_data): Remove c_style_arrays field. (language_defn::c_style_arrays_p): New member function. * m2-lang.c (m2_language_data): Remove c_style_arrays initializer. (m2_language::c_style_arrays_p): New member function. * objc-lang.c (objc_language_data): Remove c_style_arrays initializer. * opencl-lang.c (opencl_language_data): Likewise. * p-lang.c (pascal_language_data): Likewise. * rust-lang.c (rust_language_data): Likewise. * valarith.c (value_subscript): Update call to c_style_arrays_p, and update local variable to a bool. * valops.c (value_cast): Update call to c_style_arrays_p. (value_array): Likewise. * value.c (coerce_array): Likewise.
2020-07-04 16:06:08 +08:00
return type->is_vector () ? 0 : lang->c_style_arrays_p ();
default:
return 0;
}
}
/* Represents a fake method with the given parameter types. This is
used by the parser to construct a temporary "expected" type for
Make "p S::method() const::static_var" work too Trying to print a function local static variable of a const-qualified method still doesn't work after the previous fixes: (gdb) p 'S::method() const'::static_var $1 = {i1 = 1, i2 = 2, i3 = 3} (gdb) p S::method() const::static_var No symbol "static_var" in specified context. The reason is that the expression parser/evaluator loses the "const", and the above unquoted case is just like trying to print a variable of the non-const overload, if it exists, even. As if the above unquoted case had been written as: (gdb) p S::method()::static_var No symbol "static_var" in specified context. We can see the problem without static vars in the picture. With: struct S { void method (); void method () const; }; Compare: (gdb) print 'S::method(void) const' $1 = {void (const S * const)} 0x400606 <S::method() const> (gdb) print S::method(void) const $2 = {void (S * const)} 0x4005d8 <S::method()> # wrong method! That's what we need to fix. If we fix that, the function local static case starts working. The grammar production for function/method types is this one: exp: exp '(' parameter_typelist ')' const_or_volatile This results in a TYPE_INSTANCE expression evaluator operator. For the example above, we get something like this ("set debug expression 1"): ... 0 TYPE_INSTANCE 1 TypeInstance: Type @0x560fda958be0 (void) 5 OP_SCOPE Type @0x560fdaa544d8 (S) Field name: `method' ... While evaluating TYPE_INSTANCE, we end up in value_struct_elt_for_reference, trying to find the method named "method" that has the prototype recorded in TYPE_INSTANCE. In this case, TYPE_INSTANCE says that we're looking for a method that has "(void)" as parameters (that's what "1 TypeInstance: Type @0x560fda958be0 (void)" above means. The trouble is that nowhere in this mechanism do we communicate to value_struct_elt_for_reference that we're looking for the _const_ overload. value_struct_elt_for_reference only compared parameters, and the non-const "method()" overload has matching parameters, so it's considered the right match... Conveniently, the "const_or_volatile" production in the grammar already records "const" and "volatile" info in the type stack. The type stack is not used in this code path, but we can borrow the information. The patch converts the info in the type stack to an "instance flags" enum, and adds that as another element in TYPE_INSTANCE operators. This type instance flags is then applied to the temporary type that is passed to value_struct_elt_for_reference for matching. The other side of the problem is that methods in the debug info aren't marked const/volatile, so with that in place, the matching never finds const/volatile-qualified methods. The problem is that in the DWARF, there's no indication at all whether a method is const/volatile qualified... For example (c++filt applied to the linkage name for convenience): <2><d3>: Abbrev Number: 6 (DW_TAG_subprogram) <d4> DW_AT_external : 1 <d4> DW_AT_name : (indirect string, offset: 0x3df): method <d8> DW_AT_decl_file : 1 <d9> DW_AT_decl_line : 58 <da> DW_AT_linkage_name: (indirect string, offset: 0x5b2): S::method() const <de> DW_AT_declaration : 1 <de> DW_AT_object_pointer: <0xe6> <e2> DW_AT_sibling : <0xec> I see the same with both GCC and Clang. The patch works around this by extracting the cv qualification from the "const" and "volatile" in the demangled name. This will need further tweaking for "&" and "const &" overloads, but we don't support them in the parser yet, anyway. The TYPE_CONST changes were necessary otherwise the comparisons in valops.c: if (TYPE_CONST (intype) != TYPE_FN_FIELD_CONST (f, j)) continue; would fail, because when both TYPE_CONST() TYPE_FN_FIELD_CONST() were true, their values were different. BTW, I'm recording the const/volatile-ness of methods in the TYPE_FN_FIELD info because #1 - I'm not sure it's kosher to change the method's type directly (vs having to call make_cv_type to create a new type), and #2 it's what stabsread.c does: ... case 'A': /* Normal functions. */ new_sublist->fn_field.is_const = 0; new_sublist->fn_field.is_volatile = 0; (*pp)++; break; case 'B': /* `const' member functions. */ new_sublist->fn_field.is_const = 1; new_sublist->fn_field.is_volatile = 0; ... After all this, this finally all works: print S::method(void) const $1 = {void (const S * const)} 0x400606 <S::method() const> (gdb) p S::method() const::static_var $2 = {i1 = 1, i2 = 2, i3 = 3} gdb/ChangeLog: 2017-09-04 Pedro Alves <palves@redhat.com> * c-exp.y (function_method, function_method_void): Add current instance flags to TYPE_INSTANCE. * dwarf2read.c (check_modifier): New. (compute_delayed_physnames): Assert that only C++ adds delayed physnames. Mark fn_fields as const/volatile depending on physname. * eval.c (make_params): New type_instance_flags parameter. Use it as the new type's instance flags. (evaluate_subexp_standard) <TYPE_INSTANCE>: Extract the instance flags element and pass it to make_params. * expprint.c (print_subexp_standard) <TYPE_INSTANCE>: Handle instance flags element. (dump_subexp_body_standard) <TYPE_INSTANCE>: Likewise. * gdbtypes.h: Include "enum-flags.h". (type_instance_flags): New enum-flags type. (TYPE_CONST, TYPE_VOLATILE, TYPE_RESTRICT, TYPE_ATOMIC) (TYPE_CODE_SPACE, TYPE_DATA_SPACE): Return boolean. * parse.c (operator_length_standard) <TYPE_INSTANCE>: Adjust. (follow_type_instance_flags): New function. (operator_check_standard) <TYPE_INSTANCE>: Adjust. * parser-defs.h (follow_type_instance_flags): Declare. * valops.c (value_struct_elt_for_reference): const/volatile must match too. gdb/testsuite/ChangeLog: 2017-09-04 Pedro Alves <palves@redhat.com> * gdb.base/func-static.c (S::method const, S::method volatile) (S::method volatile const): New methods. (c_s, v_s, cv_s): New instances. (main): Call method() on them. * gdb.base/func-static.exp (syntax_re, cannot_resolve_re): New variables. (cannot_resolve): New procedure. (cxx_scopes_list): Test cv methods. Add print-scope-quote and print-quote-unquoted columns. (do_test): Test printing each scope too.
2017-09-05 03:21:16 +08:00
method overload resolution. FLAGS is used as instance flags of the
new type, in order to be able to make the new type represent a
const/volatile overload. */
class fake_method
{
public:
fake_method (type_instance_flags flags,
int num_types, struct type **param_types);
~fake_method ();
/* The constructed type. */
struct type *type () { return &m_type; }
private:
struct type m_type {};
main_type m_main_type {};
};
fake_method::fake_method (type_instance_flags flags,
int num_types, struct type **param_types)
{
struct type *type = &m_type;
TYPE_MAIN_TYPE (type) = &m_main_type;
type->set_length (1);
type->set_code (TYPE_CODE_METHOD);
TYPE_CHAIN (type) = type;
Use type_instance_flags more throughout A later patch in this series will rewrite enum_flags fixing some API holes. That would cause build failures around code using type_instance_flags. Or rather, that should be using it, but wasn't. This patch fixes it by using type_instance_flags throughout instead of plain integers. Note that we can't make the seemingly obvious change to struct type::instance_flags: - unsigned instance_flags : 9; + ENUM_BITFIELD (type_instance_flag_value) instance_flags : 9; Because G++ complains then that 9 bits isn't sufficient for holding all values of type_instance_flag_value. So the patch adds an type::instance_flags() method, which takes care of casting appropriately, and adds a separate type::set_instance_flags method, following the pattern of the ongoing TYPE_XXX macro elimination. This converts uses of TYPE_INSTANCE_FLAGS to type::instance_flags() in the places where the code was already being touched, but there are still many references to the TYPE_INSTANCE_FLAGS macro left behind. Those could/should be fully replaced at some point. gdb/ChangeLog: * avr-tdep.c (avr_address_class_type_flags): Return type_instance_flags. (avr_address_class_type_flags_to_name): Take a type_instance_flags. (avr_address_class_name_to_type_flags): Return bool and take a type_instance_flags. * d-lang.c (build_d_types): Use type::set_instance_flags. * ft32-tdep.c (ft32_address_class_type_flags): Return type_instance_flags. (ft32_address_class_type_flags_to_name): Take a type_instance_flags. (ft32_address_class_name_to_type_flags): Return bool and take a type_instance_flags. (ft32_gdbarch_init): Use type::set_instance_flags. * eval.c (fake_method::fake_method): Use type::set_instance_flags. * gdbarch.h, gdbarch.c: Regenerate. * gdbarch.sh (address_class_type_flags): Use type_instance_flags. (address_class_name_to_type_flags): Use type_instance_flags and bool. * gdbtypes.c (address_space_name_to_int) (address_space_int_to_name, make_qualified_type): Use type_instance_flags. (make_qualified_type): Use type_instance_flags and type::set_instance_flags. (make_type_with_address_space, make_cv_type, make_vector_type) (check_typedef): Use type_instance_flags. (recursive_dump_type): Cast type_instance_flags to unsigned for printing. (copy_type_recursive): Use type::set_instance_flags. (gdbtypes_post_init): Use type::set_instance_flags. * gdbtypes.h (struct type) <instance_flags>: Rename to ... <m_instance_flags>: ... this. <instance_flags, set_instance_flags>: New methods. (TYPE_INSTANCE_FLAGS): Use the instance_flags method. (SET_TYPE_INSTANCE_FLAGS): New. (address_space_name_to_int, address_space_int_to_name) (make_type_with_address_space): Pass flags using type_instance_flags instead of int. * stabsread.c (cleanup_undefined_types_noname): Use type::set_instance_flags. * s390-tdep.c (s390_address_class_type_flags): Return type_instance_flags. (s390_address_class_type_flags_to_name): Take a type_instance_flags. (s390_address_class_name_to_type_flags): Return bool and take a type_instance_flags. * type-stack.c (type_stack::follow_types): Use type_instance_flags. * dwarf2/read.c (read_tag_pointer_type): Use type_instance_flags.
2020-09-15 04:16:56 +08:00
type->set_instance_flags (flags);
if (num_types > 0)
{
if (param_types[num_types - 1] == NULL)
{
--num_types;
type->set_has_varargs (true);
}
else if (check_typedef (param_types[num_types - 1])->code ()
== TYPE_CODE_VOID)
{
--num_types;
/* Caller should have ensured this. */
gdb_assert (num_types == 0);
type->set_is_prototyped (true);
}
}
gdb: Don't leak memory with TYPE_ALLOC / TYPE_ZALLOC This patch started as an observation from valgrind that GDB appeared to be loosing track of some memory associated with types. An example valgrind stack would be: 24 bytes in 1 blocks are possibly lost in loss record 419 of 5,361 at 0x4C2EA1E: calloc (vg_replace_malloc.c:711) by 0x623D26: xcalloc (common-utils.c:85) by 0x623D65: xzalloc(unsigned long) (common-utils.c:95) by 0x72A066: make_function_type(type*, type**) (gdbtypes.c:510) by 0x72A098: lookup_function_type(type*) (gdbtypes.c:521) by 0x73635D: gdbtypes_post_init(gdbarch*) (gdbtypes.c:5439) by 0x727590: gdbarch_data(gdbarch*, gdbarch_data*) (gdbarch.c:5230) by 0x735B99: builtin_type(gdbarch*) (gdbtypes.c:5313) by 0x514D95: elf_rel_plt_read(minimal_symbol_reader&, objfile*, bfd_symbol**) (elfread.c:542) by 0x51662F: elf_read_minimal_symbols(objfile*, int, elfinfo const*) (elfread.c:1121) by 0x5168A5: elf_symfile_read(objfile*, enum_flags<symfile_add_flag>) (elfread.c:1207) by 0x8520F5: read_symbols(objfile*, enum_flags<symfile_add_flag>) (symfile.c:794) When we look in make_function_type we find a call to TYPE_ZALLOC (inside the INIT_FUNC_SPECIFIC macro). It is this call to TYPE_ZALLOC that is allocating memory with xcalloc, that is then getting lost. The problem is tht calling TYPE_ALLOC or TYPE_ZALLOC currently allocates memory from either the objfile obstack or by using malloc. The problem with this is that types are allocated either on the objfile obstack, or on the gdbarch obstack. As a result, if we discard a type associated with an objfile then auxiliary data allocated with TYPE_(Z)ALLOC will be correctly discarded. But, if we were ever to discard a gdbarch then any auxiliary type data would be leaked. Right now there are very few places in GDB where a gdbarch is ever discarded, but it shouldn't hurt to close down these bugs as we spot them. This commit ensures that auxiliary type data is allocated from the same obstack as the type itself, which should reduce leaked memory. The one problem case that I found with this change was in eval.c, where in one place we allocate a local type structure, and then used TYPE_ZALLOC to allocate some space for the type. This local type is neither object file owned, nor gdbarch owned, and so the updated TYPE_ALLOC code is unable to find an objstack to allocate space on. My proposed solution for this issue is that the space should be allocated with a direct call to xzalloc. We could extend TYPE_ALLOC to check for type->gdbarch being null, and then fall back to a direct call to xzalloc, however, I think that making this rare case of a local type require special handling is not a bad thing, this serves to highlight that clearing up the memory will require special handling too. This special case of a local type is interesting as the types owner field (contained within the main_type) is completely null. While reflecting on this I looked at how types use the get_type_arch function. It seems clear that, based on how this is used, it is never intended that null will be returned from this function. This only goes to reinforce, how locally alloctaed types, with no owner, are both special, and need to be handled carefully. To help spot errors earlier, I added an assert into get_type_arch that the returned arch is not null. Inside gdbarch.c I found a few other places where auxiliary type data was being allocated directly on the heap rather than on the types obstack. I have fixed these to call TYPE_ALLOC now. Finally, it is worth noting that as we don't clean up our gdbarch objects yet, then this will not make much of an impact on the amount of memory reported as lost at program termination time. Memory allocated for auxiliary type information is still not freed, however, it is now on the correct obstack. If we do ever start freeing our gdbarch structures then the associated type data will be cleaned up correctly. Tested on X86-64 GNU/Linux with no regressions. gdb/ChangeLog: * eval.c (fake_method::fake_method): Call xzalloc directly for a type that is neither object file owned, nor gdbarch owned. * gdbtypes.c (get_type_gdbarch): Add an assert that returned gdbarch is non-NULL. (alloc_type_instance): Allocate non-objfile owned types on the gdbarch obstack. (copy_type_recursive): Allocate TYPE_FIELDS and TYPE_RANGE_DATA using TYPE_ALLOC to ensure memory is allocated on the correct obstack. * gdbtypes.h (TYPE_ALLOC): Allocate space on either the objfile obstack, or the gdbarch obstack. (TYPE_ZALLOC): Rewrite using TYPE_ALLOC.
2018-09-10 20:50:34 +08:00
/* We don't use TYPE_ZALLOC here to allocate space as TYPE is owned by
neither an objfile nor a gdbarch. As a result we must manually
allocate memory for auxiliary fields, and free the memory ourselves
when we are done with it. */
type->set_num_fields (num_types);
type->set_fields
((struct field *) xzalloc (sizeof (struct field) * num_types));
while (num_types-- > 0)
type->field (num_types).set_type (param_types[num_types]);
}
fake_method::~fake_method ()
{
xfree (m_type.fields ());
}
namespace expr
{
value *
type_instance_operation::evaluate (struct type *expect_type,
struct expression *exp,
enum noside noside)
{
type_instance_flags flags = std::get<0> (m_storage);
std::vector<type *> &types = std::get<1> (m_storage);
fake_method fake_expect_type (flags, types.size (), types.data ());
return std::get<2> (m_storage)->evaluate (fake_expect_type.type (),
exp, noside);
}
}
/* Helper for evaluating an OP_VAR_VALUE. */
(Ada) fix handling of minimal symbols (UNOP_CAST and UNOP_ADDR) Consider a program which provides a symbol without debugging information. For instance, compiling the following code without -g: Some_Minimal_Symbol : Integer := 1234; pragma Export (C, Some_Minimal_Symbol, "some_minsym"); Trying to print this variable with GDB now causes an error, which is now expected: (gdb) p some_minsym 'some_minsym' has unknown type; cast it to its declared type However, trying to cast this symbol, or to take its address does not work: (gdb) p integer(some_minsym) 'some_minsym' has unknown type; cast it to its declared type (gdb) p &some_minsym 'some_minsym' has unknown type; cast it to its declared type Another manisfestation of this issue can be seen when trying to insert an Ada exception catchpoint for a specific standard exception (this only occurs if the Ada runtime is built without debugging information, which is the default). For instance: $ (gdb) catch exception constraint_error warning: failed to reevaluate internal exception condition for catchpoint 0: 'constraint_error' has unknown type; cast it to its declared type This is because, internally, the cachtpoint uses a condition referencing a minimal symbol, more precisely: long_integer (e) = long_integer (&constraint_error) This patch fixes all issues listed above: 1. resolve_subexp: Special-case the handling of OP_VAR_MSYM_VALUE expression elements, where there are no ambiguities to be resolved in that situation; 2. ada_evaluate_subexp: Enhance the handling of the UNOP_CAST handling so as to process the case where the target of the cast is a minimal symbol (as well as a symbol with debugging information). This mimics what's done in C. gdb/ChangeLog: * ada-lang.c (resolve_subexp): Add handling of OP_VAR_MSYM_VALUE. (ada_evaluate_subexp_for_cast): New function. (ada_evaluate_subexp) <UNOP_CAST>: Replace code by call to ada_evaluate_subexp_for_cast. (ada_evaluate_subexp) <nosideret>: Replace code by call to eval_skip_value. * eval.c (evaluate_var_value): Make non-static. (evaluate_var_msym_value, eval_skip_value): Likewise. * value.h (evaluate_var_value, evaluate_var_msym_value) (eval_skip_value): Declare. gdb/testsuite/ChangeLog: * gdb.ada/minsyms: New testcase. Tested on x86_64-linux. No regression. Fixes the following failures: catch_ex.exp: continuing to Program_Error exception catch_ex.exp: continuing to failed assertion catch_ex.exp: continuing to unhandled exception catch_ex.exp: continuing to program completion complete.exp: p <Exported_Capitalized> complete.exp: p Exported_Capitalized complete.exp: p exported_capitalized mi_catch_ex.exp: catch Program_Error (unexpected output) mi_catch_ex.exp: continue to exception catchpoint hit (unknown output after running) mi_catch_ex.exp: continue to assert failure catchpoint hit (unknown output after running) mi_catch_ex.exp: continue to unhandled exception catchpoint hit (unknown output after running) mi_ex_cond.exp: catch C_E if i = 2 (unexpected output)
2017-11-16 08:02:33 +08:00
value *
evaluate_var_value (enum noside noside, const block *blk, symbol *var)
{
/* JYG: We used to just return value::zero of the symbol type if
we're asked to avoid side effects. Otherwise we return
value_of_variable (...). However I'm not sure if
value_of_variable () has any side effect. We need a full value
object returned here for whatis_exp () to call evaluate_type ()
and then pass the full value to value_rtti_target_type () if we
are dealing with a pointer or reference to a base class and print
object is on. */
struct value *ret = NULL;
Rewrite TRY/CATCH This rewrites gdb's TRY/CATCH to plain C++ try/catch. The patch was largely written by script, though one change (to a comment in common-exceptions.h) was reverted by hand. gdb/ChangeLog 2019-04-08 Tom Tromey <tom@tromey.com> * xml-support.c: Use C++ exception handling. * x86-linux-nat.c: Use C++ exception handling. * windows-nat.c: Use C++ exception handling. * varobj.c: Use C++ exception handling. * value.c: Use C++ exception handling. * valprint.c: Use C++ exception handling. * valops.c: Use C++ exception handling. * unittests/parse-connection-spec-selftests.c: Use C++ exception handling. * unittests/cli-utils-selftests.c: Use C++ exception handling. * typeprint.c: Use C++ exception handling. * tui/tui.c: Use C++ exception handling. * tracefile-tfile.c: Use C++ exception handling. * top.c: Use C++ exception handling. * thread.c: Use C++ exception handling. * target.c: Use C++ exception handling. * symmisc.c: Use C++ exception handling. * symfile-mem.c: Use C++ exception handling. * stack.c: Use C++ exception handling. * sparc64-linux-tdep.c: Use C++ exception handling. * solib.c: Use C++ exception handling. * solib-svr4.c: Use C++ exception handling. * solib-spu.c: Use C++ exception handling. * solib-frv.c: Use C++ exception handling. * solib-dsbt.c: Use C++ exception handling. * selftest-arch.c: Use C++ exception handling. * s390-tdep.c: Use C++ exception handling. * rust-lang.c: Use C++ exception handling. * rust-exp.y: Use C++ exception handling. * rs6000-tdep.c: Use C++ exception handling. * rs6000-aix-tdep.c: Use C++ exception handling. * riscv-tdep.c: Use C++ exception handling. * remote.c: Use C++ exception handling. * remote-fileio.c: Use C++ exception handling. * record-full.c: Use C++ exception handling. * record-btrace.c: Use C++ exception handling. * python/python.c: Use C++ exception handling. * python/py-value.c: Use C++ exception handling. * python/py-utils.c: Use C++ exception handling. * python/py-unwind.c: Use C++ exception handling. * python/py-type.c: Use C++ exception handling. * python/py-symbol.c: Use C++ exception handling. * python/py-record.c: Use C++ exception handling. * python/py-record-btrace.c: Use C++ exception handling. * python/py-progspace.c: Use C++ exception handling. * python/py-prettyprint.c: Use C++ exception handling. * python/py-param.c: Use C++ exception handling. * python/py-objfile.c: Use C++ exception handling. * python/py-linetable.c: Use C++ exception handling. * python/py-lazy-string.c: Use C++ exception handling. * python/py-infthread.c: Use C++ exception handling. * python/py-inferior.c: Use C++ exception handling. * python/py-gdb-readline.c: Use C++ exception handling. * python/py-framefilter.c: Use C++ exception handling. * python/py-frame.c: Use C++ exception handling. * python/py-finishbreakpoint.c: Use C++ exception handling. * python/py-cmd.c: Use C++ exception handling. * python/py-breakpoint.c: Use C++ exception handling. * python/py-arch.c: Use C++ exception handling. * printcmd.c: Use C++ exception handling. * ppc-linux-tdep.c: Use C++ exception handling. * parse.c: Use C++ exception handling. * p-valprint.c: Use C++ exception handling. * objc-lang.c: Use C++ exception handling. * mi/mi-main.c: Use C++ exception handling. * mi/mi-interp.c: Use C++ exception handling. * mi/mi-cmd-stack.c: Use C++ exception handling. * mi/mi-cmd-break.c: Use C++ exception handling. * main.c: Use C++ exception handling. * linux-thread-db.c: Use C++ exception handling. * linux-tdep.c: Use C++ exception handling. * linux-nat.c: Use C++ exception handling. * linux-fork.c: Use C++ exception handling. * linespec.c: Use C++ exception handling. * language.c: Use C++ exception handling. * jit.c: Use C++ exception handling. * infrun.c: Use C++ exception handling. * infcmd.c: Use C++ exception handling. * infcall.c: Use C++ exception handling. * inf-loop.c: Use C++ exception handling. * i386-tdep.c: Use C++ exception handling. * i386-linux-tdep.c: Use C++ exception handling. * guile/scm-value.c: Use C++ exception handling. * guile/scm-type.c: Use C++ exception handling. * guile/scm-symtab.c: Use C++ exception handling. * guile/scm-symbol.c: Use C++ exception handling. * guile/scm-pretty-print.c: Use C++ exception handling. * guile/scm-ports.c: Use C++ exception handling. * guile/scm-param.c: Use C++ exception handling. * guile/scm-math.c: Use C++ exception handling. * guile/scm-lazy-string.c: Use C++ exception handling. * guile/scm-frame.c: Use C++ exception handling. * guile/scm-disasm.c: Use C++ exception handling. * guile/scm-cmd.c: Use C++ exception handling. * guile/scm-breakpoint.c: Use C++ exception handling. * guile/scm-block.c: Use C++ exception handling. * guile/guile-internal.h: Use C++ exception handling. * gnu-v3-abi.c: Use C++ exception handling. * gdbtypes.c: Use C++ exception handling. * frame.c: Use C++ exception handling. * frame-unwind.c: Use C++ exception handling. * fbsd-tdep.c: Use C++ exception handling. * f-valprint.c: Use C++ exception handling. * exec.c: Use C++ exception handling. * event-top.c: Use C++ exception handling. * event-loop.c: Use C++ exception handling. * eval.c: Use C++ exception handling. * dwarf2read.c: Use C++ exception handling. * dwarf2loc.c: Use C++ exception handling. * dwarf2-frame.c: Use C++ exception handling. * dwarf2-frame-tailcall.c: Use C++ exception handling. * dwarf-index-write.c: Use C++ exception handling. * dwarf-index-cache.c: Use C++ exception handling. * dtrace-probe.c: Use C++ exception handling. * disasm-selftests.c: Use C++ exception handling. * darwin-nat.c: Use C++ exception handling. * cp-valprint.c: Use C++ exception handling. * cp-support.c: Use C++ exception handling. * cp-abi.c: Use C++ exception handling. * corelow.c: Use C++ exception handling. * completer.c: Use C++ exception handling. * compile/compile-object-run.c: Use C++ exception handling. * compile/compile-object-load.c: Use C++ exception handling. * compile/compile-cplus-symbols.c: Use C++ exception handling. * compile/compile-c-symbols.c: Use C++ exception handling. * common/selftest.c: Use C++ exception handling. * common/new-op.c: Use C++ exception handling. * cli/cli-script.c: Use C++ exception handling. * cli/cli-interp.c: Use C++ exception handling. * cli/cli-cmds.c: Use C++ exception handling. * c-varobj.c: Use C++ exception handling. * btrace.c: Use C++ exception handling. * breakpoint.c: Use C++ exception handling. * break-catch-throw.c: Use C++ exception handling. * arch-utils.c: Use C++ exception handling. * amd64-tdep.c: Use C++ exception handling. * ada-valprint.c: Use C++ exception handling. * ada-typeprint.c: Use C++ exception handling. * ada-lang.c: Use C++ exception handling. * aarch64-tdep.c: Use C++ exception handling. gdb/gdbserver/ChangeLog 2019-04-08 Tom Tromey <tom@tromey.com> * server.c: Use C++ exception handling. * linux-low.c: Use C++ exception handling. * gdbreplay.c: Use C++ exception handling.
2019-04-04 06:02:42 +08:00
try
{
ret = value_of_variable (var, blk);
}
Rename gdb exception types This renames the gdb exception types. The old types were only needed due to the macros in common-exception.h that are now gone. The intermediate layer of gdb_exception_RETURN_MASK_ALL did not seem needed, so this patch removes it entirely. gdb/ChangeLog 2019-04-08 Tom Tromey <tom@tromey.com> * common/common-exceptions.h (gdb_exception_RETURN_MASK_ALL): Remove. (gdb_exception_error): Rename from gdb_exception_RETURN_MASK_ERROR. (gdb_exception_quit): Rename from gdb_exception_RETURN_MASK_QUIT. (gdb_quit_bad_alloc): Update. * aarch64-tdep.c: Update. * ada-lang.c: Update. * ada-typeprint.c: Update. * ada-valprint.c: Update. * amd64-tdep.c: Update. * arch-utils.c: Update. * break-catch-throw.c: Update. * breakpoint.c: Update. * btrace.c: Update. * c-varobj.c: Update. * cli/cli-cmds.c: Update. * cli/cli-interp.c: Update. * cli/cli-script.c: Update. * common/common-exceptions.c: Update. * common/new-op.c: Update. * common/selftest.c: Update. * compile/compile-c-symbols.c: Update. * compile/compile-cplus-symbols.c: Update. * compile/compile-object-load.c: Update. * compile/compile-object-run.c: Update. * completer.c: Update. * corelow.c: Update. * cp-abi.c: Update. * cp-support.c: Update. * cp-valprint.c: Update. * darwin-nat.c: Update. * disasm-selftests.c: Update. * dtrace-probe.c: Update. * dwarf-index-cache.c: Update. * dwarf-index-write.c: Update. * dwarf2-frame-tailcall.c: Update. * dwarf2-frame.c: Update. * dwarf2loc.c: Update. * dwarf2read.c: Update. * eval.c: Update. * event-loop.c: Update. * event-top.c: Update. * exec.c: Update. * f-valprint.c: Update. * fbsd-tdep.c: Update. * frame-unwind.c: Update. * frame.c: Update. * gdbtypes.c: Update. * gnu-v3-abi.c: Update. * guile/guile-internal.h: Update. * guile/scm-block.c: Update. * guile/scm-breakpoint.c: Update. * guile/scm-cmd.c: Update. * guile/scm-disasm.c: Update. * guile/scm-frame.c: Update. * guile/scm-lazy-string.c: Update. * guile/scm-math.c: Update. * guile/scm-param.c: Update. * guile/scm-ports.c: Update. * guile/scm-pretty-print.c: Update. * guile/scm-symbol.c: Update. * guile/scm-symtab.c: Update. * guile/scm-type.c: Update. * guile/scm-value.c: Update. * i386-linux-tdep.c: Update. * i386-tdep.c: Update. * inf-loop.c: Update. * infcall.c: Update. * infcmd.c: Update. * infrun.c: Update. * jit.c: Update. * language.c: Update. * linespec.c: Update. * linux-fork.c: Update. * linux-nat.c: Update. * linux-tdep.c: Update. * linux-thread-db.c: Update. * main.c: Update. * mi/mi-cmd-break.c: Update. * mi/mi-cmd-stack.c: Update. * mi/mi-interp.c: Update. * mi/mi-main.c: Update. * objc-lang.c: Update. * p-valprint.c: Update. * parse.c: Update. * ppc-linux-tdep.c: Update. * printcmd.c: Update. * python/py-arch.c: Update. * python/py-breakpoint.c: Update. * python/py-cmd.c: Update. * python/py-finishbreakpoint.c: Update. * python/py-frame.c: Update. * python/py-framefilter.c: Update. * python/py-gdb-readline.c: Update. * python/py-inferior.c: Update. * python/py-infthread.c: Update. * python/py-lazy-string.c: Update. * python/py-linetable.c: Update. * python/py-objfile.c: Update. * python/py-param.c: Update. * python/py-prettyprint.c: Update. * python/py-progspace.c: Update. * python/py-record-btrace.c: Update. * python/py-record.c: Update. * python/py-symbol.c: Update. * python/py-type.c: Update. * python/py-unwind.c: Update. * python/py-utils.c: Update. * python/py-value.c: Update. * python/python.c: Update. * record-btrace.c: Update. * record-full.c: Update. * remote-fileio.c: Update. * remote.c: Update. * riscv-tdep.c: Update. * rs6000-aix-tdep.c: Update. * rs6000-tdep.c: Update. * rust-exp.y: Update. * rust-lang.c: Update. * s390-tdep.c: Update. * selftest-arch.c: Update. * solib-dsbt.c: Update. * solib-frv.c: Update. * solib-spu.c: Update. * solib-svr4.c: Update. * solib.c: Update. * sparc64-linux-tdep.c: Update. * stack.c: Update. * symfile-mem.c: Update. * symmisc.c: Update. * target.c: Update. * thread.c: Update. * top.c: Update. * tracefile-tfile.c: Update. * tui/tui.c: Update. * typeprint.c: Update. * unittests/cli-utils-selftests.c: Update. * unittests/parse-connection-spec-selftests.c: Update. * valops.c: Update. * valprint.c: Update. * value.c: Update. * varobj.c: Update. * windows-nat.c: Update. * x86-linux-nat.c: Update. * xml-support.c: Update. gdb/gdbserver/ChangeLog 2019-04-08 Tom Tromey <tom@tromey.com> * gdbreplay.c: Update. * linux-low.c: Update. * server.c: Update.
2019-04-04 05:59:07 +08:00
catch (const gdb_exception_error &except)
{
if (noside != EVAL_AVOID_SIDE_EFFECTS)
Replace throw_exception with throw in some cases This replaces throw_exception with "throw;" when possible. This was written by script. The rule that is followed is that uses of the form: catch (... &name) { ... throw_exception (name); } ... can be rewritten. This should always be safe, because exceptions are caught by const reference, and therefore can't be modified in the body of the catch. gdb/ChangeLog 2019-04-08 Tom Tromey <tom@tromey.com> * valops.c (value_rtti_indirect_type): Replace throw_exception with throw. * tracefile-tfile.c (tfile_target_open): Replace throw_exception with throw. * thread.c (thr_try_catch_cmd): Replace throw_exception with throw. * target.c (target_translate_tls_address): Replace throw_exception with throw. * stack.c (frame_apply_command_count): Replace throw_exception with throw. * solib-spu.c (append_ocl_sos): Replace throw_exception with throw. * s390-tdep.c (s390_frame_unwind_cache): Replace throw_exception with throw. * rs6000-tdep.c (rs6000_frame_cache) (rs6000_epilogue_frame_cache): Replace throw_exception with throw. * remote.c: Replace throw_exception with throw. * record-full.c (record_full_message, record_full_wait_1) (record_full_restore): Replace throw_exception with throw. * record-btrace.c: (get_thread_current_frame_id, record_btrace_start_replaying) (cmd_record_btrace_bts_start, cmd_record_btrace_pt_start) (cmd_record_btrace_start): Replace throw_exception with throw. * parse.c (parse_exp_in_context_1): Replace throw_exception with throw. * linux-nat.c (detach_one_lwp, linux_resume_one_lwp) (resume_stopped_resumed_lwps): Replace throw_exception with throw. * linespec.c: (find_linespec_symbols): Replace throw_exception with throw. * infrun.c (displaced_step_prepare, resume): Replace throw_exception with throw. * infcmd.c (post_create_inferior): Replace throw_exception with throw. * inf-loop.c (inferior_event_handler): Replace throw_exception with throw. * i386-tdep.c (i386_frame_cache, i386_epilogue_frame_cache) (i386_sigtramp_frame_cache): Replace throw_exception with throw. * frame.c (frame_unwind_pc, get_prev_frame_if_no_cycle) (get_prev_frame_always, get_frame_pc_if_available) (get_frame_address_in_block_if_available, get_frame_language): Replace throw_exception with throw. * frame-unwind.c (frame_unwind_try_unwinder): Replace throw_exception with throw. * eval.c (fetch_subexp_value, evaluate_var_value) (evaluate_funcall, evaluate_subexp_standard): Replace throw_exception with throw. * dwarf2loc.c (call_site_find_chain) (dwarf2_evaluate_loc_desc_full, dwarf2_locexpr_baton_eval): Replace throw_exception with throw. * dwarf2-frame.c (dwarf2_frame_cache): Replace throw_exception with throw. * darwin-nat.c (darwin_attach_pid): Replace throw_exception with throw. * cp-abi.c (baseclass_offset): Replace throw_exception with throw. * completer.c (complete_line_internal): Replace throw_exception with throw. * compile/compile-object-run.c (compile_object_run): Replace throw_exception with throw. * cli/cli-script.c (process_next_line): Replace throw_exception with throw. * btrace.c (btrace_compute_ftrace_pt, btrace_compute_ftrace) (btrace_enable, btrace_maint_update_pt_packets): Replace throw_exception with throw. * breakpoint.c (create_breakpoint, save_breakpoints): Replace throw_exception with throw. * break-catch-throw.c (re_set_exception_catchpoint): Replace throw_exception with throw. * amd64-tdep.c (amd64_frame_cache, amd64_sigtramp_frame_cache) (amd64_epilogue_frame_cache): Replace throw_exception with throw. * aarch64-tdep.c (aarch64_make_prologue_cache) (aarch64_make_stub_cache): Replace throw_exception with throw. gdb/gdbserver/ChangeLog 2019-04-08 Tom Tromey <tom@tromey.com> * linux-low.c (linux_detach_one_lwp): Replace throw_exception with throw. (linux_resume_one_lwp): Likewise.
2019-01-29 01:45:45 +08:00
throw;
ret = value::zero (var->type (), not_lval);
}
return ret;
}
namespace expr
{
value *
var_value_operation::evaluate (struct type *expect_type,
struct expression *exp,
enum noside noside)
{
Use block_symbol in var_value_operation I noticed that var_value_operation takes a block and a symbol, and most callers destructure a block_symbol to pass in. It seems better for this class to simply hold a block_symbol instead. Tested on x86-64 Fedora 32. gdb/ChangeLog 2021-04-15 Tom Tromey <tromey@adacore.com> * rust-exp.y (rust_parser::convert_ast_to_expression): Update. * parse.c (parser_state::push_symbol, parser_state::push_dollar): Update. * p-exp.y (variable): Update. * m2-exp.y (variable): Update. * go-exp.y (variable): Update. * expprint.c (dump_for_expression): New overload. * expop.h (check_objfile): New overload. (check_constant): New overload. (class var_value_operation): Use block_symbol. <get_symbol>: Rewrite. * eval.c (var_value_operation::evaluate) (var_value_operation::evaluate_funcall) (var_value_operation::evaluate_for_address) (var_value_operation::evaluate_for_address) (var_value_operation::evaluate_with_coercion) (var_value_operation::evaluate_for_sizeof) (var_value_operation::evaluate_for_cast): Update. * d-exp.y (PrimaryExpression): Update. * c-exp.y (variable): Update. * ax-gdb.c (var_value_operation::do_generate_ax): Update. * ada-lang.c (ada_var_value_operation::evaluate_for_cast) (ada_var_value_operation::evaluate) (ada_var_value_operation::resolve) (ada_funcall_operation::resolve): Update. * ada-exp.y (write_var_from_sym, write_object_renaming) (write_ambiguous_var, write_var_or_type, write_name_assoc) (maybe_overload): Update. * ada-exp.h (class ada_var_value_operation) <get_block>: Rewrite.
2021-04-16 00:05:00 +08:00
symbol *var = std::get<0> (m_storage).symbol;
if (var->type ()->code () == TYPE_CODE_ERROR)
error_unknown_type (var->print_name ());
Use block_symbol in var_value_operation I noticed that var_value_operation takes a block and a symbol, and most callers destructure a block_symbol to pass in. It seems better for this class to simply hold a block_symbol instead. Tested on x86-64 Fedora 32. gdb/ChangeLog 2021-04-15 Tom Tromey <tromey@adacore.com> * rust-exp.y (rust_parser::convert_ast_to_expression): Update. * parse.c (parser_state::push_symbol, parser_state::push_dollar): Update. * p-exp.y (variable): Update. * m2-exp.y (variable): Update. * go-exp.y (variable): Update. * expprint.c (dump_for_expression): New overload. * expop.h (check_objfile): New overload. (check_constant): New overload. (class var_value_operation): Use block_symbol. <get_symbol>: Rewrite. * eval.c (var_value_operation::evaluate) (var_value_operation::evaluate_funcall) (var_value_operation::evaluate_for_address) (var_value_operation::evaluate_for_address) (var_value_operation::evaluate_with_coercion) (var_value_operation::evaluate_for_sizeof) (var_value_operation::evaluate_for_cast): Update. * d-exp.y (PrimaryExpression): Update. * c-exp.y (variable): Update. * ax-gdb.c (var_value_operation::do_generate_ax): Update. * ada-lang.c (ada_var_value_operation::evaluate_for_cast) (ada_var_value_operation::evaluate) (ada_var_value_operation::resolve) (ada_funcall_operation::resolve): Update. * ada-exp.y (write_var_from_sym, write_object_renaming) (write_ambiguous_var, write_var_or_type, write_name_assoc) (maybe_overload): Update. * ada-exp.h (class ada_var_value_operation) <get_block>: Rewrite.
2021-04-16 00:05:00 +08:00
return evaluate_var_value (noside, std::get<0> (m_storage).block, var);
}
} /* namespace expr */
Introduce OP_VAR_MSYM_VALUE The previous patch left GDB with an inconsistency. While with normal expression evaluation the "unknown return type" error shows the name of the function that misses debug info: (gdb) p getenv ("PATH") 'getenv' has unknown return type; cast the call to its declared return type ^^^^^^ which can by handy in more complicated expressions, "ptype" does not: (gdb) ptype getenv ("PATH") function has unknown return type; cast the call to its declared return type ^^^^^^^^ This commit is a step toward fixing it. The problem is that while evaluating the expression above, we have no reference to the minimal symbol where we could extract the name from. This is because the resulting expression tree has no reference to the minsym at all. During parsing, the type and address of the minsym are extracted and an UNOP_MEMVAL / UNOP_MEMVAL_TLS operator is generated (see write_exp_elt_msym). With "set debug expression", here's what you see: 0 OP_FUNCALL Number of args: 0 3 UNOP_MEMVAL Type @0x565334a51930 (<text variable, no debug info>) 6 OP_LONG Type @0x565334a51c60 (__CORE_ADDR), value 140737345035648 (0x7ffff7751d80) The "print" case finds the function name, because call_function_by_hand looks up the function by address again. However, for "ptype", we don't reach that code, because obviously we don't really call the function. Unlike minsym references, references to variables with debug info have a pointer to the variable's symbol in the expression tree, with OP_VAR_VALUE: (gdb) ptype main() ... 0 OP_FUNCALL Number of args: 0 3 OP_VAR_VALUE Block @0x0, symbol @0x559bbbd9b358 (main(int, char**)) ... so I don't see why do minsyms need to be different. So to prepare for fixing the missing function name issue, this commit adds a new OP_VAR_MSYM_VALUE operator that mimics OP_VAR_VALUE, except that it's for minsyms instead of debug symbols. For infcalls, we now get expressions like these: 0 OP_FUNCALL Number of args: 0 3 OP_VAR_MSYM_VALUE Objfile @0x1e41bf0, msymbol @0x7fffe599b000 (getenv) In the following patch, we'll make OP_FUNCALL extract the function name from the symbol stored in OP_VAR_VALUE/OP_VAR_MSYM_VALUE. OP_VAR_MSYM_VALUE will be used more in a later patch in the series too. gdb/ChangeLog: 2017-09-04 Pedro Alves <palves@redhat.com> * ada-lang.c (resolve_subexp): Handle OP_VAR_MSYM_VALUE. * ax-gdb.c (gen_msym_var_ref): New function. (gen_expr): Handle OP_VAR_MSYM_VALUE. * eval.c (evaluate_var_msym_value): New function. * eval.c (evaluate_subexp_standard): Handle OP_VAR_MSYM_VALUE. <OP_FUNCALL>: Extract function name from symbol/minsym and pass it to call_function_by_hand. * expprint.c (print_subexp_standard, dump_subexp_body_standard): Handle OP_VAR_MSYM_VALUE. (union exp_element) <msymbol>: New field. * minsyms.h (struct type): Forward declare. (find_minsym_type_and_address): Declare. * parse.c (write_exp_elt_msym): New function. (write_exp_msymbol): Delete, refactored as ... (find_minsym_type_and_address): ... this new function. (write_exp_msymbol): Reimplement using OP_VAR_MSYM_VALUE. (operator_length_standard, operator_check_standard): Handle OP_VAR_MSYM_VALUE. * std-operator.def (OP_VAR_MSYM_VALUE): New.
2017-09-05 03:21:13 +08:00
/* Helper for evaluating an OP_VAR_MSYM_VALUE. */
(Ada) fix handling of minimal symbols (UNOP_CAST and UNOP_ADDR) Consider a program which provides a symbol without debugging information. For instance, compiling the following code without -g: Some_Minimal_Symbol : Integer := 1234; pragma Export (C, Some_Minimal_Symbol, "some_minsym"); Trying to print this variable with GDB now causes an error, which is now expected: (gdb) p some_minsym 'some_minsym' has unknown type; cast it to its declared type However, trying to cast this symbol, or to take its address does not work: (gdb) p integer(some_minsym) 'some_minsym' has unknown type; cast it to its declared type (gdb) p &some_minsym 'some_minsym' has unknown type; cast it to its declared type Another manisfestation of this issue can be seen when trying to insert an Ada exception catchpoint for a specific standard exception (this only occurs if the Ada runtime is built without debugging information, which is the default). For instance: $ (gdb) catch exception constraint_error warning: failed to reevaluate internal exception condition for catchpoint 0: 'constraint_error' has unknown type; cast it to its declared type This is because, internally, the cachtpoint uses a condition referencing a minimal symbol, more precisely: long_integer (e) = long_integer (&constraint_error) This patch fixes all issues listed above: 1. resolve_subexp: Special-case the handling of OP_VAR_MSYM_VALUE expression elements, where there are no ambiguities to be resolved in that situation; 2. ada_evaluate_subexp: Enhance the handling of the UNOP_CAST handling so as to process the case where the target of the cast is a minimal symbol (as well as a symbol with debugging information). This mimics what's done in C. gdb/ChangeLog: * ada-lang.c (resolve_subexp): Add handling of OP_VAR_MSYM_VALUE. (ada_evaluate_subexp_for_cast): New function. (ada_evaluate_subexp) <UNOP_CAST>: Replace code by call to ada_evaluate_subexp_for_cast. (ada_evaluate_subexp) <nosideret>: Replace code by call to eval_skip_value. * eval.c (evaluate_var_value): Make non-static. (evaluate_var_msym_value, eval_skip_value): Likewise. * value.h (evaluate_var_value, evaluate_var_msym_value) (eval_skip_value): Declare. gdb/testsuite/ChangeLog: * gdb.ada/minsyms: New testcase. Tested on x86_64-linux. No regression. Fixes the following failures: catch_ex.exp: continuing to Program_Error exception catch_ex.exp: continuing to failed assertion catch_ex.exp: continuing to unhandled exception catch_ex.exp: continuing to program completion complete.exp: p <Exported_Capitalized> complete.exp: p Exported_Capitalized complete.exp: p exported_capitalized mi_catch_ex.exp: catch Program_Error (unexpected output) mi_catch_ex.exp: continue to exception catchpoint hit (unknown output after running) mi_catch_ex.exp: continue to assert failure catchpoint hit (unknown output after running) mi_catch_ex.exp: continue to unhandled exception catchpoint hit (unknown output after running) mi_ex_cond.exp: catch C_E if i = 2 (unexpected output)
2017-11-16 08:02:33 +08:00
value *
Introduce OP_VAR_MSYM_VALUE The previous patch left GDB with an inconsistency. While with normal expression evaluation the "unknown return type" error shows the name of the function that misses debug info: (gdb) p getenv ("PATH") 'getenv' has unknown return type; cast the call to its declared return type ^^^^^^ which can by handy in more complicated expressions, "ptype" does not: (gdb) ptype getenv ("PATH") function has unknown return type; cast the call to its declared return type ^^^^^^^^ This commit is a step toward fixing it. The problem is that while evaluating the expression above, we have no reference to the minimal symbol where we could extract the name from. This is because the resulting expression tree has no reference to the minsym at all. During parsing, the type and address of the minsym are extracted and an UNOP_MEMVAL / UNOP_MEMVAL_TLS operator is generated (see write_exp_elt_msym). With "set debug expression", here's what you see: 0 OP_FUNCALL Number of args: 0 3 UNOP_MEMVAL Type @0x565334a51930 (<text variable, no debug info>) 6 OP_LONG Type @0x565334a51c60 (__CORE_ADDR), value 140737345035648 (0x7ffff7751d80) The "print" case finds the function name, because call_function_by_hand looks up the function by address again. However, for "ptype", we don't reach that code, because obviously we don't really call the function. Unlike minsym references, references to variables with debug info have a pointer to the variable's symbol in the expression tree, with OP_VAR_VALUE: (gdb) ptype main() ... 0 OP_FUNCALL Number of args: 0 3 OP_VAR_VALUE Block @0x0, symbol @0x559bbbd9b358 (main(int, char**)) ... so I don't see why do minsyms need to be different. So to prepare for fixing the missing function name issue, this commit adds a new OP_VAR_MSYM_VALUE operator that mimics OP_VAR_VALUE, except that it's for minsyms instead of debug symbols. For infcalls, we now get expressions like these: 0 OP_FUNCALL Number of args: 0 3 OP_VAR_MSYM_VALUE Objfile @0x1e41bf0, msymbol @0x7fffe599b000 (getenv) In the following patch, we'll make OP_FUNCALL extract the function name from the symbol stored in OP_VAR_VALUE/OP_VAR_MSYM_VALUE. OP_VAR_MSYM_VALUE will be used more in a later patch in the series too. gdb/ChangeLog: 2017-09-04 Pedro Alves <palves@redhat.com> * ada-lang.c (resolve_subexp): Handle OP_VAR_MSYM_VALUE. * ax-gdb.c (gen_msym_var_ref): New function. (gen_expr): Handle OP_VAR_MSYM_VALUE. * eval.c (evaluate_var_msym_value): New function. * eval.c (evaluate_subexp_standard): Handle OP_VAR_MSYM_VALUE. <OP_FUNCALL>: Extract function name from symbol/minsym and pass it to call_function_by_hand. * expprint.c (print_subexp_standard, dump_subexp_body_standard): Handle OP_VAR_MSYM_VALUE. (union exp_element) <msymbol>: New field. * minsyms.h (struct type): Forward declare. (find_minsym_type_and_address): Declare. * parse.c (write_exp_elt_msym): New function. (write_exp_msymbol): Delete, refactored as ... (find_minsym_type_and_address): ... this new function. (write_exp_msymbol): Reimplement using OP_VAR_MSYM_VALUE. (operator_length_standard, operator_check_standard): Handle OP_VAR_MSYM_VALUE. * std-operator.def (OP_VAR_MSYM_VALUE): New.
2017-09-05 03:21:13 +08:00
evaluate_var_msym_value (enum noside noside,
struct objfile *objfile, minimal_symbol *msymbol)
{
Calling ifunc functions when target has no debug info but resolver has After the previous patch, on Fedora 27 (glibc 2.26), if you try calling strlen in the inferior, you now get: (top-gdb) p strlen ("hello") '__strlen_avx2' has unknown return type; cast the call to its declared return type This is correct, because __strlen_avx2 is written in assembly. We can improve on this though -- if the final ifunc resolved/target function has no debug info, but the ifunc _resolver_ does have debug info, we can try extracting the final function's type from the type that the resolver returns. E.g.,: typedef size_t (*strlen_t) (const char*); size_t my_strlen (const char *) { /* some implementation */ } strlen_t strlen_resolver (unsigned long hwcap) { return my_strlen; } extern size_t strlen (const char *s); __typeof (strlen) strlen __attribute__ ((ifunc ("strlen_resolver"))); In the strlen example above, the resolver returns strlen_t, which is a typedef for pointer to a function that returns size_t. "strlen_t" is the type of both the user-visible "strlen", and of the the target function that implements it. This patch teaches GDB to extract that type. This is done for actual inferior function calls (in infcall.c), and for ptype (in eval_call). By the time we get to either of these places, we've already lost the original symbol/minsym, and only have values and types to work with. Hence the changes to c-exp.y and evaluate_var_msym_value, to ensure that we propagate the ifunc minsymbol's info. The change to make ifunc symbols have no/unknown return type exposes a latent problem -- gdb.compile/compile-ifunc.exp calls a no-debug-info function, but we did not warn about it. The test is fixed by this commit too. gdb/ChangeLog: 2018-04-26 Pedro Alves <palves@redhat.com> * blockframe.c (find_gnu_ifunc_target_type): New function. (find_function_type): New. * eval.c (evaluate_var_msym_value): For GNU ifunc types, always return a value with a memory address. (eval_call): For calls to GNU ifunc functions, try to find the type of the target function from the type that the resolver returns. * gdbtypes.c (objfile_type): Don't install a return type for ifunc symbols. * infcall.c (find_function_return_type): Delete. (find_function_addr): Add 'function_type' parameter. For calls to GNU ifunc functions, try to find the type of the target function from the type that the resolver returns, and return it via FUNCTION_TYPE. (call_function_by_hand_dummy): Adjust to use the function type returned by find_function_addr. (find_function_addr): Add 'function_type' parameter and move description here. * symtab.h (find_function_type, find_gnu_ifunc_target_type): New declarations. gdb/testsuite/ChangeLog: 2018-04-26 Pedro Alves <palves@redhat.com> * gdb.compile/compile-ifunc.exp: Also expect "function has unknown return type" warnings.
2018-04-26 20:01:26 +08:00
CORE_ADDR address;
type *the_type = find_minsym_type_and_address (msymbol, objfile, &address);
if (noside == EVAL_AVOID_SIDE_EFFECTS && !the_type->is_gnu_ifunc ())
return value::zero (the_type, not_lval);
Introduce OP_VAR_MSYM_VALUE The previous patch left GDB with an inconsistency. While with normal expression evaluation the "unknown return type" error shows the name of the function that misses debug info: (gdb) p getenv ("PATH") 'getenv' has unknown return type; cast the call to its declared return type ^^^^^^ which can by handy in more complicated expressions, "ptype" does not: (gdb) ptype getenv ("PATH") function has unknown return type; cast the call to its declared return type ^^^^^^^^ This commit is a step toward fixing it. The problem is that while evaluating the expression above, we have no reference to the minimal symbol where we could extract the name from. This is because the resulting expression tree has no reference to the minsym at all. During parsing, the type and address of the minsym are extracted and an UNOP_MEMVAL / UNOP_MEMVAL_TLS operator is generated (see write_exp_elt_msym). With "set debug expression", here's what you see: 0 OP_FUNCALL Number of args: 0 3 UNOP_MEMVAL Type @0x565334a51930 (<text variable, no debug info>) 6 OP_LONG Type @0x565334a51c60 (__CORE_ADDR), value 140737345035648 (0x7ffff7751d80) The "print" case finds the function name, because call_function_by_hand looks up the function by address again. However, for "ptype", we don't reach that code, because obviously we don't really call the function. Unlike minsym references, references to variables with debug info have a pointer to the variable's symbol in the expression tree, with OP_VAR_VALUE: (gdb) ptype main() ... 0 OP_FUNCALL Number of args: 0 3 OP_VAR_VALUE Block @0x0, symbol @0x559bbbd9b358 (main(int, char**)) ... so I don't see why do minsyms need to be different. So to prepare for fixing the missing function name issue, this commit adds a new OP_VAR_MSYM_VALUE operator that mimics OP_VAR_VALUE, except that it's for minsyms instead of debug symbols. For infcalls, we now get expressions like these: 0 OP_FUNCALL Number of args: 0 3 OP_VAR_MSYM_VALUE Objfile @0x1e41bf0, msymbol @0x7fffe599b000 (getenv) In the following patch, we'll make OP_FUNCALL extract the function name from the symbol stored in OP_VAR_VALUE/OP_VAR_MSYM_VALUE. OP_VAR_MSYM_VALUE will be used more in a later patch in the series too. gdb/ChangeLog: 2017-09-04 Pedro Alves <palves@redhat.com> * ada-lang.c (resolve_subexp): Handle OP_VAR_MSYM_VALUE. * ax-gdb.c (gen_msym_var_ref): New function. (gen_expr): Handle OP_VAR_MSYM_VALUE. * eval.c (evaluate_var_msym_value): New function. * eval.c (evaluate_subexp_standard): Handle OP_VAR_MSYM_VALUE. <OP_FUNCALL>: Extract function name from symbol/minsym and pass it to call_function_by_hand. * expprint.c (print_subexp_standard, dump_subexp_body_standard): Handle OP_VAR_MSYM_VALUE. (union exp_element) <msymbol>: New field. * minsyms.h (struct type): Forward declare. (find_minsym_type_and_address): Declare. * parse.c (write_exp_elt_msym): New function. (write_exp_msymbol): Delete, refactored as ... (find_minsym_type_and_address): ... this new function. (write_exp_msymbol): Reimplement using OP_VAR_MSYM_VALUE. (operator_length_standard, operator_check_standard): Handle OP_VAR_MSYM_VALUE. * std-operator.def (OP_VAR_MSYM_VALUE): New.
2017-09-05 03:21:13 +08:00
else
Calling ifunc functions when target has no debug info but resolver has After the previous patch, on Fedora 27 (glibc 2.26), if you try calling strlen in the inferior, you now get: (top-gdb) p strlen ("hello") '__strlen_avx2' has unknown return type; cast the call to its declared return type This is correct, because __strlen_avx2 is written in assembly. We can improve on this though -- if the final ifunc resolved/target function has no debug info, but the ifunc _resolver_ does have debug info, we can try extracting the final function's type from the type that the resolver returns. E.g.,: typedef size_t (*strlen_t) (const char*); size_t my_strlen (const char *) { /* some implementation */ } strlen_t strlen_resolver (unsigned long hwcap) { return my_strlen; } extern size_t strlen (const char *s); __typeof (strlen) strlen __attribute__ ((ifunc ("strlen_resolver"))); In the strlen example above, the resolver returns strlen_t, which is a typedef for pointer to a function that returns size_t. "strlen_t" is the type of both the user-visible "strlen", and of the the target function that implements it. This patch teaches GDB to extract that type. This is done for actual inferior function calls (in infcall.c), and for ptype (in eval_call). By the time we get to either of these places, we've already lost the original symbol/minsym, and only have values and types to work with. Hence the changes to c-exp.y and evaluate_var_msym_value, to ensure that we propagate the ifunc minsymbol's info. The change to make ifunc symbols have no/unknown return type exposes a latent problem -- gdb.compile/compile-ifunc.exp calls a no-debug-info function, but we did not warn about it. The test is fixed by this commit too. gdb/ChangeLog: 2018-04-26 Pedro Alves <palves@redhat.com> * blockframe.c (find_gnu_ifunc_target_type): New function. (find_function_type): New. * eval.c (evaluate_var_msym_value): For GNU ifunc types, always return a value with a memory address. (eval_call): For calls to GNU ifunc functions, try to find the type of the target function from the type that the resolver returns. * gdbtypes.c (objfile_type): Don't install a return type for ifunc symbols. * infcall.c (find_function_return_type): Delete. (find_function_addr): Add 'function_type' parameter. For calls to GNU ifunc functions, try to find the type of the target function from the type that the resolver returns, and return it via FUNCTION_TYPE. (call_function_by_hand_dummy): Adjust to use the function type returned by find_function_addr. (find_function_addr): Add 'function_type' parameter and move description here. * symtab.h (find_function_type, find_gnu_ifunc_target_type): New declarations. gdb/testsuite/ChangeLog: 2018-04-26 Pedro Alves <palves@redhat.com> * gdb.compile/compile-ifunc.exp: Also expect "function has unknown return type" warnings.
2018-04-26 20:01:26 +08:00
return value_at_lazy (the_type, address);
Introduce OP_VAR_MSYM_VALUE The previous patch left GDB with an inconsistency. While with normal expression evaluation the "unknown return type" error shows the name of the function that misses debug info: (gdb) p getenv ("PATH") 'getenv' has unknown return type; cast the call to its declared return type ^^^^^^ which can by handy in more complicated expressions, "ptype" does not: (gdb) ptype getenv ("PATH") function has unknown return type; cast the call to its declared return type ^^^^^^^^ This commit is a step toward fixing it. The problem is that while evaluating the expression above, we have no reference to the minimal symbol where we could extract the name from. This is because the resulting expression tree has no reference to the minsym at all. During parsing, the type and address of the minsym are extracted and an UNOP_MEMVAL / UNOP_MEMVAL_TLS operator is generated (see write_exp_elt_msym). With "set debug expression", here's what you see: 0 OP_FUNCALL Number of args: 0 3 UNOP_MEMVAL Type @0x565334a51930 (<text variable, no debug info>) 6 OP_LONG Type @0x565334a51c60 (__CORE_ADDR), value 140737345035648 (0x7ffff7751d80) The "print" case finds the function name, because call_function_by_hand looks up the function by address again. However, for "ptype", we don't reach that code, because obviously we don't really call the function. Unlike minsym references, references to variables with debug info have a pointer to the variable's symbol in the expression tree, with OP_VAR_VALUE: (gdb) ptype main() ... 0 OP_FUNCALL Number of args: 0 3 OP_VAR_VALUE Block @0x0, symbol @0x559bbbd9b358 (main(int, char**)) ... so I don't see why do minsyms need to be different. So to prepare for fixing the missing function name issue, this commit adds a new OP_VAR_MSYM_VALUE operator that mimics OP_VAR_VALUE, except that it's for minsyms instead of debug symbols. For infcalls, we now get expressions like these: 0 OP_FUNCALL Number of args: 0 3 OP_VAR_MSYM_VALUE Objfile @0x1e41bf0, msymbol @0x7fffe599b000 (getenv) In the following patch, we'll make OP_FUNCALL extract the function name from the symbol stored in OP_VAR_VALUE/OP_VAR_MSYM_VALUE. OP_VAR_MSYM_VALUE will be used more in a later patch in the series too. gdb/ChangeLog: 2017-09-04 Pedro Alves <palves@redhat.com> * ada-lang.c (resolve_subexp): Handle OP_VAR_MSYM_VALUE. * ax-gdb.c (gen_msym_var_ref): New function. (gen_expr): Handle OP_VAR_MSYM_VALUE. * eval.c (evaluate_var_msym_value): New function. * eval.c (evaluate_subexp_standard): Handle OP_VAR_MSYM_VALUE. <OP_FUNCALL>: Extract function name from symbol/minsym and pass it to call_function_by_hand. * expprint.c (print_subexp_standard, dump_subexp_body_standard): Handle OP_VAR_MSYM_VALUE. (union exp_element) <msymbol>: New field. * minsyms.h (struct type): Forward declare. (find_minsym_type_and_address): Declare. * parse.c (write_exp_elt_msym): New function. (write_exp_msymbol): Delete, refactored as ... (find_minsym_type_and_address): ... this new function. (write_exp_msymbol): Reimplement using OP_VAR_MSYM_VALUE. (operator_length_standard, operator_check_standard): Handle OP_VAR_MSYM_VALUE. * std-operator.def (OP_VAR_MSYM_VALUE): New.
2017-09-05 03:21:13 +08:00
}
gdb/fortran: Move Fortran expression handling into f-lang.c The Fortran specific OP_F77_UNDETERMINED_ARGLIST is currently handled in the generic expression handling code. There's no reason why this should be the case, so this commit moves handling of this into Fortran specific files. There should be no user visible changes after this commit. gdb/ChangeLog: * eval.c: Remove 'f-lang.h' include. (value_f90_subarray): Moved to f-lang.c. (eval_call): Renamed to... (evaluate_subexp_do_call): ...this, is no longer static, header comment moved into header file. (evaluate_funcall): Update call to eval_call. (skip_undetermined_arglist): Moved to f-lang.c. (fortran_value_subarray): Likewise. (evaluate_subexp_standard): OP_F77_UNDETERMINED_ARGLIST handling moved to evaluate_subexp_f. (calc_f77_array_dims): Moved to f-lang.c * expprint.c (print_subexp_funcall): New function. (print_subexp_standard): OP_F77_UNDETERMINED_ARGLIST handling moved to print_subexp_f, OP_FUNCALL uses new function. (dump_subexp_body_funcall): New function. (dump_subexp_body_standard): OP_F77_UNDETERMINED_ARGLIST handling moved to dump_subexp_f, OP_FUNCALL uses new function. * expression.h (evaluate_subexp_do_call): Declare. * f-lang.c (value_f90_subarray): Moved from eval.c. (skip_undetermined_arglist): Likewise. (calc_f77_array_dims): Likewise. (fortran_value_subarray): Likewise. (evaluate_subexp_f): Add OP_F77_UNDETERMINED_ARGLIST support. (operator_length_f): Likewise. (print_subexp_f): Likewise. (dump_subexp_body_f): Likewise. * fortran-operator.def (OP_F77_UNDETERMINED_ARGLIST): Move declaration of this operation to here. * parse.c (operator_length_standard): OP_F77_UNDETERMINED_ARGLIST support moved to operator_length_f. * parser-defs.h (dump_subexp_body_funcall): Declare. (print_subexp_funcall): Declare. * std-operator.def (OP_F77_UNDETERMINED_ARGLIST): Moved to fortran-operator.def.
2020-05-07 23:27:16 +08:00
/* See expression.h. */
gdb/fortran: Move Fortran expression handling into f-lang.c The Fortran specific OP_F77_UNDETERMINED_ARGLIST is currently handled in the generic expression handling code. There's no reason why this should be the case, so this commit moves handling of this into Fortran specific files. There should be no user visible changes after this commit. gdb/ChangeLog: * eval.c: Remove 'f-lang.h' include. (value_f90_subarray): Moved to f-lang.c. (eval_call): Renamed to... (evaluate_subexp_do_call): ...this, is no longer static, header comment moved into header file. (evaluate_funcall): Update call to eval_call. (skip_undetermined_arglist): Moved to f-lang.c. (fortran_value_subarray): Likewise. (evaluate_subexp_standard): OP_F77_UNDETERMINED_ARGLIST handling moved to evaluate_subexp_f. (calc_f77_array_dims): Moved to f-lang.c * expprint.c (print_subexp_funcall): New function. (print_subexp_standard): OP_F77_UNDETERMINED_ARGLIST handling moved to print_subexp_f, OP_FUNCALL uses new function. (dump_subexp_body_funcall): New function. (dump_subexp_body_standard): OP_F77_UNDETERMINED_ARGLIST handling moved to dump_subexp_f, OP_FUNCALL uses new function. * expression.h (evaluate_subexp_do_call): Declare. * f-lang.c (value_f90_subarray): Moved from eval.c. (skip_undetermined_arglist): Likewise. (calc_f77_array_dims): Likewise. (fortran_value_subarray): Likewise. (evaluate_subexp_f): Add OP_F77_UNDETERMINED_ARGLIST support. (operator_length_f): Likewise. (print_subexp_f): Likewise. (dump_subexp_body_f): Likewise. * fortran-operator.def (OP_F77_UNDETERMINED_ARGLIST): Move declaration of this operation to here. * parse.c (operator_length_standard): OP_F77_UNDETERMINED_ARGLIST support moved to operator_length_f. * parser-defs.h (dump_subexp_body_funcall): Declare. (print_subexp_funcall): Declare. * std-operator.def (OP_F77_UNDETERMINED_ARGLIST): Moved to fortran-operator.def.
2020-05-07 23:27:16 +08:00
value *
evaluate_subexp_do_call (expression *exp, enum noside noside,
value *callee,
gdb::array_view<value *> argvec,
gdb/fortran: Move Fortran expression handling into f-lang.c The Fortran specific OP_F77_UNDETERMINED_ARGLIST is currently handled in the generic expression handling code. There's no reason why this should be the case, so this commit moves handling of this into Fortran specific files. There should be no user visible changes after this commit. gdb/ChangeLog: * eval.c: Remove 'f-lang.h' include. (value_f90_subarray): Moved to f-lang.c. (eval_call): Renamed to... (evaluate_subexp_do_call): ...this, is no longer static, header comment moved into header file. (evaluate_funcall): Update call to eval_call. (skip_undetermined_arglist): Moved to f-lang.c. (fortran_value_subarray): Likewise. (evaluate_subexp_standard): OP_F77_UNDETERMINED_ARGLIST handling moved to evaluate_subexp_f. (calc_f77_array_dims): Moved to f-lang.c * expprint.c (print_subexp_funcall): New function. (print_subexp_standard): OP_F77_UNDETERMINED_ARGLIST handling moved to print_subexp_f, OP_FUNCALL uses new function. (dump_subexp_body_funcall): New function. (dump_subexp_body_standard): OP_F77_UNDETERMINED_ARGLIST handling moved to dump_subexp_f, OP_FUNCALL uses new function. * expression.h (evaluate_subexp_do_call): Declare. * f-lang.c (value_f90_subarray): Moved from eval.c. (skip_undetermined_arglist): Likewise. (calc_f77_array_dims): Likewise. (fortran_value_subarray): Likewise. (evaluate_subexp_f): Add OP_F77_UNDETERMINED_ARGLIST support. (operator_length_f): Likewise. (print_subexp_f): Likewise. (dump_subexp_body_f): Likewise. * fortran-operator.def (OP_F77_UNDETERMINED_ARGLIST): Move declaration of this operation to here. * parse.c (operator_length_standard): OP_F77_UNDETERMINED_ARGLIST support moved to operator_length_f. * parser-defs.h (dump_subexp_body_funcall): Declare. (print_subexp_funcall): Declare. * std-operator.def (OP_F77_UNDETERMINED_ARGLIST): Moved to fortran-operator.def.
2020-05-07 23:27:16 +08:00
const char *function_name,
type *default_return_type)
{
if (callee == NULL)
error (_("Cannot evaluate function -- may be inlined"));
type *ftype = callee->type ();
/* If the callee is a struct, there might be a user-defined function call
operator that should be used instead. */
std::vector<value *> vals;
if (overload_resolution
&& exp->language_defn->la_language == language_cplus
&& check_typedef (ftype)->code () == TYPE_CODE_STRUCT)
{
/* Include space for the `this' pointer at the start. */
vals.resize (argvec.size () + 1);
vals[0] = value_addr (callee);
for (int i = 0; i < argvec.size (); ++i)
vals[i + 1] = argvec[i];
int static_memfuncp;
find_overload_match (vals, "operator()", METHOD, &vals[0], nullptr,
&callee, nullptr, &static_memfuncp, 0, noside);
if (!static_memfuncp)
argvec = vals;
ftype = callee->type ();
}
if (noside == EVAL_AVOID_SIDE_EFFECTS)
{
/* If the return type doesn't look like a function type,
call an error. This can happen if somebody tries to turn
a variable into a function call. */
if (ftype->code () == TYPE_CODE_INTERNAL_FUNCTION)
{
/* The call to call_internal_function below handles noside. */
}
else if (ftype->code () == TYPE_CODE_XMETHOD)
{
type *return_type = callee->result_type_of_xmethod (argvec);
if (return_type == NULL)
error (_("Xmethod is missing return type."));
return value::zero (return_type, not_lval);
}
else if (ftype->code () == TYPE_CODE_FUNC
|| ftype->code () == TYPE_CODE_METHOD)
{
if (ftype->is_gnu_ifunc ())
Calling ifunc functions when target has no debug info but resolver has After the previous patch, on Fedora 27 (glibc 2.26), if you try calling strlen in the inferior, you now get: (top-gdb) p strlen ("hello") '__strlen_avx2' has unknown return type; cast the call to its declared return type This is correct, because __strlen_avx2 is written in assembly. We can improve on this though -- if the final ifunc resolved/target function has no debug info, but the ifunc _resolver_ does have debug info, we can try extracting the final function's type from the type that the resolver returns. E.g.,: typedef size_t (*strlen_t) (const char*); size_t my_strlen (const char *) { /* some implementation */ } strlen_t strlen_resolver (unsigned long hwcap) { return my_strlen; } extern size_t strlen (const char *s); __typeof (strlen) strlen __attribute__ ((ifunc ("strlen_resolver"))); In the strlen example above, the resolver returns strlen_t, which is a typedef for pointer to a function that returns size_t. "strlen_t" is the type of both the user-visible "strlen", and of the the target function that implements it. This patch teaches GDB to extract that type. This is done for actual inferior function calls (in infcall.c), and for ptype (in eval_call). By the time we get to either of these places, we've already lost the original symbol/minsym, and only have values and types to work with. Hence the changes to c-exp.y and evaluate_var_msym_value, to ensure that we propagate the ifunc minsymbol's info. The change to make ifunc symbols have no/unknown return type exposes a latent problem -- gdb.compile/compile-ifunc.exp calls a no-debug-info function, but we did not warn about it. The test is fixed by this commit too. gdb/ChangeLog: 2018-04-26 Pedro Alves <palves@redhat.com> * blockframe.c (find_gnu_ifunc_target_type): New function. (find_function_type): New. * eval.c (evaluate_var_msym_value): For GNU ifunc types, always return a value with a memory address. (eval_call): For calls to GNU ifunc functions, try to find the type of the target function from the type that the resolver returns. * gdbtypes.c (objfile_type): Don't install a return type for ifunc symbols. * infcall.c (find_function_return_type): Delete. (find_function_addr): Add 'function_type' parameter. For calls to GNU ifunc functions, try to find the type of the target function from the type that the resolver returns, and return it via FUNCTION_TYPE. (call_function_by_hand_dummy): Adjust to use the function type returned by find_function_addr. (find_function_addr): Add 'function_type' parameter and move description here. * symtab.h (find_function_type, find_gnu_ifunc_target_type): New declarations. gdb/testsuite/ChangeLog: 2018-04-26 Pedro Alves <palves@redhat.com> * gdb.compile/compile-ifunc.exp: Also expect "function has unknown return type" warnings.
2018-04-26 20:01:26 +08:00
{
CORE_ADDR address = callee->address ();
Calling ifunc functions when target has no debug info but resolver has After the previous patch, on Fedora 27 (glibc 2.26), if you try calling strlen in the inferior, you now get: (top-gdb) p strlen ("hello") '__strlen_avx2' has unknown return type; cast the call to its declared return type This is correct, because __strlen_avx2 is written in assembly. We can improve on this though -- if the final ifunc resolved/target function has no debug info, but the ifunc _resolver_ does have debug info, we can try extracting the final function's type from the type that the resolver returns. E.g.,: typedef size_t (*strlen_t) (const char*); size_t my_strlen (const char *) { /* some implementation */ } strlen_t strlen_resolver (unsigned long hwcap) { return my_strlen; } extern size_t strlen (const char *s); __typeof (strlen) strlen __attribute__ ((ifunc ("strlen_resolver"))); In the strlen example above, the resolver returns strlen_t, which is a typedef for pointer to a function that returns size_t. "strlen_t" is the type of both the user-visible "strlen", and of the the target function that implements it. This patch teaches GDB to extract that type. This is done for actual inferior function calls (in infcall.c), and for ptype (in eval_call). By the time we get to either of these places, we've already lost the original symbol/minsym, and only have values and types to work with. Hence the changes to c-exp.y and evaluate_var_msym_value, to ensure that we propagate the ifunc minsymbol's info. The change to make ifunc symbols have no/unknown return type exposes a latent problem -- gdb.compile/compile-ifunc.exp calls a no-debug-info function, but we did not warn about it. The test is fixed by this commit too. gdb/ChangeLog: 2018-04-26 Pedro Alves <palves@redhat.com> * blockframe.c (find_gnu_ifunc_target_type): New function. (find_function_type): New. * eval.c (evaluate_var_msym_value): For GNU ifunc types, always return a value with a memory address. (eval_call): For calls to GNU ifunc functions, try to find the type of the target function from the type that the resolver returns. * gdbtypes.c (objfile_type): Don't install a return type for ifunc symbols. * infcall.c (find_function_return_type): Delete. (find_function_addr): Add 'function_type' parameter. For calls to GNU ifunc functions, try to find the type of the target function from the type that the resolver returns, and return it via FUNCTION_TYPE. (call_function_by_hand_dummy): Adjust to use the function type returned by find_function_addr. (find_function_addr): Add 'function_type' parameter and move description here. * symtab.h (find_function_type, find_gnu_ifunc_target_type): New declarations. gdb/testsuite/ChangeLog: 2018-04-26 Pedro Alves <palves@redhat.com> * gdb.compile/compile-ifunc.exp: Also expect "function has unknown return type" warnings.
2018-04-26 20:01:26 +08:00
type *resolved_type = find_gnu_ifunc_target_type (address);
if (resolved_type != NULL)
ftype = resolved_type;
}
type *return_type = ftype->target_type ();
if (return_type == NULL)
return_type = default_return_type;
if (return_type == NULL)
error_call_unknown_return_type (function_name);
return value::allocate (return_type);
}
else
error (_("Expression of type other than "
"\"Function returning ...\" used as function"));
}
switch (callee->type ()->code ())
{
case TYPE_CODE_INTERNAL_FUNCTION:
return call_internal_function (exp->gdbarch, exp->language_defn,
callee, argvec.size (), argvec.data (),
noside);
case TYPE_CODE_XMETHOD:
return callee->call_xmethod (argvec);
default:
return call_function_by_hand (callee, default_return_type, argvec);
}
}
namespace expr
{
value *
operation::evaluate_funcall (struct type *expect_type,
struct expression *exp,
enum noside noside,
const char *function_name,
const std::vector<operation_up> &args)
{
std::vector<value *> vals (args.size ());
value *callee = evaluate_with_coercion (exp, noside);
struct type *type = callee->type ();
if (type->code () == TYPE_CODE_PTR)
type = type->target_type ();
/* If type is a struct, num_fields would refer to the number of
members in the type, not the number of arguments. */
bool type_has_arguments
= type->code () == TYPE_CODE_FUNC || type->code () == TYPE_CODE_METHOD;
for (int i = 0; i < args.size (); ++i)
{
if (type_has_arguments && i < type->num_fields ())
vals[i] = args[i]->evaluate (type->field (i).type (), exp, noside);
else
vals[i] = args[i]->evaluate_with_coercion (exp, noside);
}
return evaluate_subexp_do_call (exp, noside, callee, vals,
function_name, expect_type);
}
value *
var_value_operation::evaluate_funcall (struct type *expect_type,
struct expression *exp,
enum noside noside,
const std::vector<operation_up> &args)
{
if (!overload_resolution
|| exp->language_defn->la_language != language_cplus)
return operation::evaluate_funcall (expect_type, exp, noside, args);
std::vector<value *> argvec (args.size ());
for (int i = 0; i < args.size (); ++i)
argvec[i] = args[i]->evaluate_with_coercion (exp, noside);
struct symbol *symp;
find_overload_match (argvec, NULL, NON_METHOD,
Use block_symbol in var_value_operation I noticed that var_value_operation takes a block and a symbol, and most callers destructure a block_symbol to pass in. It seems better for this class to simply hold a block_symbol instead. Tested on x86-64 Fedora 32. gdb/ChangeLog 2021-04-15 Tom Tromey <tromey@adacore.com> * rust-exp.y (rust_parser::convert_ast_to_expression): Update. * parse.c (parser_state::push_symbol, parser_state::push_dollar): Update. * p-exp.y (variable): Update. * m2-exp.y (variable): Update. * go-exp.y (variable): Update. * expprint.c (dump_for_expression): New overload. * expop.h (check_objfile): New overload. (check_constant): New overload. (class var_value_operation): Use block_symbol. <get_symbol>: Rewrite. * eval.c (var_value_operation::evaluate) (var_value_operation::evaluate_funcall) (var_value_operation::evaluate_for_address) (var_value_operation::evaluate_for_address) (var_value_operation::evaluate_with_coercion) (var_value_operation::evaluate_for_sizeof) (var_value_operation::evaluate_for_cast): Update. * d-exp.y (PrimaryExpression): Update. * c-exp.y (variable): Update. * ax-gdb.c (var_value_operation::do_generate_ax): Update. * ada-lang.c (ada_var_value_operation::evaluate_for_cast) (ada_var_value_operation::evaluate) (ada_var_value_operation::resolve) (ada_funcall_operation::resolve): Update. * ada-exp.y (write_var_from_sym, write_object_renaming) (write_ambiguous_var, write_var_or_type, write_name_assoc) (maybe_overload): Update. * ada-exp.h (class ada_var_value_operation) <get_block>: Rewrite.
2021-04-16 00:05:00 +08:00
NULL, std::get<0> (m_storage).symbol,
NULL, &symp, NULL, 0, noside);
if (symp->type ()->code () == TYPE_CODE_ERROR)
error_unknown_type (symp->print_name ());
Use block_symbol in var_value_operation I noticed that var_value_operation takes a block and a symbol, and most callers destructure a block_symbol to pass in. It seems better for this class to simply hold a block_symbol instead. Tested on x86-64 Fedora 32. gdb/ChangeLog 2021-04-15 Tom Tromey <tromey@adacore.com> * rust-exp.y (rust_parser::convert_ast_to_expression): Update. * parse.c (parser_state::push_symbol, parser_state::push_dollar): Update. * p-exp.y (variable): Update. * m2-exp.y (variable): Update. * go-exp.y (variable): Update. * expprint.c (dump_for_expression): New overload. * expop.h (check_objfile): New overload. (check_constant): New overload. (class var_value_operation): Use block_symbol. <get_symbol>: Rewrite. * eval.c (var_value_operation::evaluate) (var_value_operation::evaluate_funcall) (var_value_operation::evaluate_for_address) (var_value_operation::evaluate_for_address) (var_value_operation::evaluate_with_coercion) (var_value_operation::evaluate_for_sizeof) (var_value_operation::evaluate_for_cast): Update. * d-exp.y (PrimaryExpression): Update. * c-exp.y (variable): Update. * ax-gdb.c (var_value_operation::do_generate_ax): Update. * ada-lang.c (ada_var_value_operation::evaluate_for_cast) (ada_var_value_operation::evaluate) (ada_var_value_operation::resolve) (ada_funcall_operation::resolve): Update. * ada-exp.y (write_var_from_sym, write_object_renaming) (write_ambiguous_var, write_var_or_type, write_name_assoc) (maybe_overload): Update. * ada-exp.h (class ada_var_value_operation) <get_block>: Rewrite.
2021-04-16 00:05:00 +08:00
value *callee = evaluate_var_value (noside, std::get<0> (m_storage).block,
symp);
return evaluate_subexp_do_call (exp, noside, callee, argvec,
nullptr, expect_type);
}
value *
scope_operation::evaluate_funcall (struct type *expect_type,
struct expression *exp,
enum noside noside,
const std::vector<operation_up> &args)
{
if (!overload_resolution
|| exp->language_defn->la_language != language_cplus)
return operation::evaluate_funcall (expect_type, exp, noside, args);
/* Unpack it locally so we can properly handle overload
resolution. */
const std::string &name = std::get<1> (m_storage);
struct type *type = std::get<0> (m_storage);
symbol *function = NULL;
const char *function_name = NULL;
std::vector<value *> argvec (1 + args.size ());
if (type->code () == TYPE_CODE_NAMESPACE)
{
function = cp_lookup_symbol_namespace (type->name (),
name.c_str (),
get_selected_block (0),
SEARCH_FUNCTION_DOMAIN).symbol;
if (function == NULL)
error (_("No symbol \"%s\" in namespace \"%s\"."),
name.c_str (), type->name ());
}
else
{
gdb_assert (type->code () == TYPE_CODE_STRUCT
|| type->code () == TYPE_CODE_UNION);
function_name = name.c_str ();
/* We need a properly typed value for method lookup. */
argvec[0] = value::zero (type, lval_memory);
}
for (int i = 0; i < args.size (); ++i)
argvec[i + 1] = args[i]->evaluate_with_coercion (exp, noside);
gdb::array_view<value *> arg_view = argvec;
value *callee = nullptr;
if (function_name != nullptr)
{
int static_memfuncp;
find_overload_match (arg_view, function_name, METHOD,
&argvec[0], nullptr, &callee, nullptr,
&static_memfuncp, 0, noside);
if (!static_memfuncp)
{
/* For the time being, we don't handle this. */
error (_("Call to overloaded function %s requires "
"`this' pointer"),
function_name);
}
arg_view = arg_view.slice (1);
}
else
{
symbol *symp;
arg_view = arg_view.slice (1);
find_overload_match (arg_view, nullptr,
NON_METHOD, nullptr, function,
nullptr, &symp, nullptr, 1, noside);
callee = value_of_variable (symp, get_selected_block (0));
}
return evaluate_subexp_do_call (exp, noside, callee, arg_view,
nullptr, expect_type);
}
value *
structop_member_base::evaluate_funcall (struct type *expect_type,
struct expression *exp,
enum noside noside,
const std::vector<operation_up> &args)
{
/* First, evaluate the structure into lhs. */
value *lhs;
if (opcode () == STRUCTOP_MEMBER)
lhs = std::get<0> (m_storage)->evaluate_for_address (exp, noside);
else
lhs = std::get<0> (m_storage)->evaluate (nullptr, exp, noside);
std::vector<value *> vals (args.size () + 1);
gdb::array_view<value *> val_view = vals;
/* If the function is a virtual function, then the aggregate
value (providing the structure) plays its part by providing
the vtable. Otherwise, it is just along for the ride: call
the function directly. */
value *rhs = std::get<1> (m_storage)->evaluate (nullptr, exp, noside);
value *callee;
type *a1_type = check_typedef (rhs->type ());
if (a1_type->code () == TYPE_CODE_METHODPTR)
{
if (noside == EVAL_AVOID_SIDE_EFFECTS)
callee = value::zero (a1_type->target_type (), not_lval);
else
callee = cplus_method_ptr_to_value (&lhs, rhs);
vals[0] = lhs;
}
else if (a1_type->code () == TYPE_CODE_MEMBERPTR)
{
struct type *type_ptr
= lookup_pointer_type (TYPE_SELF_TYPE (a1_type));
struct type *target_type_ptr
= lookup_pointer_type (a1_type->target_type ());
/* Now, convert this value to an address. */
lhs = value_cast (type_ptr, lhs);
long mem_offset = value_as_long (rhs);
callee = value_from_pointer (target_type_ptr,
value_as_long (lhs) + mem_offset);
callee = value_ind (callee);
val_view = val_view.slice (1);
}
else
error (_("Non-pointer-to-member value used in pointer-to-member "
"construct"));
for (int i = 0; i < args.size (); ++i)
vals[i + 1] = args[i]->evaluate_with_coercion (exp, noside);
return evaluate_subexp_do_call (exp, noside, callee, val_view,
nullptr, expect_type);
}
value *
structop_base_operation::evaluate_funcall
(struct type *expect_type, struct expression *exp, enum noside noside,
const std::vector<operation_up> &args)
{
gdb: replace NULL terminated array with array_view After the previous commit, this commit updates the value_struct_elt function to take an array_view rather than a NULL terminated array of values. The requirement for a NULL terminated array of values actually stems from typecmp, so the change from an array to array_view needs to be propagated through to this function. While making this change I noticed that this fixes another bug, in value_x_binop and value_x_unop GDB creates an array of values which doesn't have a NULL at the end. An array_view of this array is passed to value_user_defined_op, which then unpacks the array_view and passed the raw array to value_struct_elt, but only if the language is not C++. As value_x_binop and value_x_unop can only request member functions with the names of C++ operators, then most of the time, assuming the inferior is not a C++ program, then GDB will not find a matching member function with the call to value_struct_elt, and so typecmp will never be called, and so, GDB will avoid undefined behaviour. However, it is worth remembering that, when GDB's language is set to "auto", the current language is selected based on the language of the current compilation unit. As C++ programs usually link against libc, which is written in C, then, if the inferior is stopped in libc GDB will set the language to C. And so, it is possible that we will end up using value_struct_elt to try and lookup, and match, a C++ operator. If this occurs then GDB will experience undefined behaviour. I have extended the test added in the previous commit to also cover this case. Finally, this commit changes the API from passing around a pointer to an array to passing around a pointer to an array_view. The reason for this is that we need to be able to distinguish between the cases where we call value_struct_elt with no arguments, i.e. we are looking up a struct member, but we either don't have the arguments we want to pass yet, or we don't expect there to be any need for GDB to use the argument types to resolve any overloading; and the second case where we call value_struct_elt looking for a function that takes no arguments, that is, the argument list is empty. NOTE: While writing this I realise that if we pass an array_view at all then it will always have at least one item in it, the `this' pointer for the object we are planning to call the method on. So we could, I guess, pass an empty array_view to indicate the case where we don't know anything about the arguments, and when the array_view is length 1 or more, it means we do have the arguments. However, though we could do this, I don't think this would be better, the length 0 vs length 1 difference seems a little too subtle, I think that there's a better solution... I think a better solution would be to wrap the array_view in a gdb::optional, this would make the whole, do we have an array view or not question explicit. I haven't done this as part of this commit as making that change is much more extensive, every user of value_struct_elt will need to be updated, and as this commit already contains a bug fix, I wanted to keep the large refactoring in a separate commit, so, check out the next commit for the use of gdb::optional. gdb/ChangeLog: PR gdb/27994 * eval.c (structop_base_operation::evaluate_funcall): Pass array_view instead of array to value_struct_elt. * valarith.c (value_user_defined_op): Likewise. * valops.c (typecmp): Change parameter type from array pointer to array_view. Update header comment, and update body accordingly. (search_struct_method): Likewise. (value_struct_elt): Likewise. * value.h (value_struct_elt): Update declaration. gdb/testsuite/ChangeLog: PR gdb/27994 * gdb.cp/method-call-in-c.cc (struct foo_type): Add operator+=, change initial value of var member variable. (main): Make use of foo_type's operator+=. * gdb.cp/method-call-in-c.exp: Test use of operator+=.
2021-06-22 17:17:53 +08:00
/* Allocate space for the function call arguments, Including space for a
`this' pointer at the start. */
std::vector<value *> vals (args.size () + 1);
/* First, evaluate the structure into vals[0]. */
enum exp_opcode op = opcode ();
if (op == STRUCTOP_STRUCT)
{
/* If v is a variable in a register, and the user types
v.method (), this will produce an error, because v has no
address.
A possible way around this would be to allocate a copy of
the variable on the stack, copy in the contents, call the
function, and copy out the contents. I.e. convert this
from call by reference to call by copy-return (or
whatever it's called). However, this does not work
because it is not the same: the method being called could
stash a copy of the address, and then future uses through
that address (after the method returns) would be expected
to use the variable itself, not some copy of it. */
vals[0] = std::get<0> (m_storage)->evaluate_for_address (exp, noside);
}
else
{
vals[0] = std::get<0> (m_storage)->evaluate (nullptr, exp, noside);
/* Check to see if the operator '->' has been overloaded.
If the operator has been overloaded replace vals[0] with the
value returned by the custom operator and continue
evaluation. */
while (unop_user_defined_p (op, vals[0]))
{
struct value *value = nullptr;
try
{
value = value_x_unop (vals[0], op, noside);
}
catch (const gdb_exception_error &except)
{
if (except.error == NOT_FOUND_ERROR)
break;
else
throw;
}
vals[0] = value;
}
}
gdb: replace NULL terminated array with array_view After the previous commit, this commit updates the value_struct_elt function to take an array_view rather than a NULL terminated array of values. The requirement for a NULL terminated array of values actually stems from typecmp, so the change from an array to array_view needs to be propagated through to this function. While making this change I noticed that this fixes another bug, in value_x_binop and value_x_unop GDB creates an array of values which doesn't have a NULL at the end. An array_view of this array is passed to value_user_defined_op, which then unpacks the array_view and passed the raw array to value_struct_elt, but only if the language is not C++. As value_x_binop and value_x_unop can only request member functions with the names of C++ operators, then most of the time, assuming the inferior is not a C++ program, then GDB will not find a matching member function with the call to value_struct_elt, and so typecmp will never be called, and so, GDB will avoid undefined behaviour. However, it is worth remembering that, when GDB's language is set to "auto", the current language is selected based on the language of the current compilation unit. As C++ programs usually link against libc, which is written in C, then, if the inferior is stopped in libc GDB will set the language to C. And so, it is possible that we will end up using value_struct_elt to try and lookup, and match, a C++ operator. If this occurs then GDB will experience undefined behaviour. I have extended the test added in the previous commit to also cover this case. Finally, this commit changes the API from passing around a pointer to an array to passing around a pointer to an array_view. The reason for this is that we need to be able to distinguish between the cases where we call value_struct_elt with no arguments, i.e. we are looking up a struct member, but we either don't have the arguments we want to pass yet, or we don't expect there to be any need for GDB to use the argument types to resolve any overloading; and the second case where we call value_struct_elt looking for a function that takes no arguments, that is, the argument list is empty. NOTE: While writing this I realise that if we pass an array_view at all then it will always have at least one item in it, the `this' pointer for the object we are planning to call the method on. So we could, I guess, pass an empty array_view to indicate the case where we don't know anything about the arguments, and when the array_view is length 1 or more, it means we do have the arguments. However, though we could do this, I don't think this would be better, the length 0 vs length 1 difference seems a little too subtle, I think that there's a better solution... I think a better solution would be to wrap the array_view in a gdb::optional, this would make the whole, do we have an array view or not question explicit. I haven't done this as part of this commit as making that change is much more extensive, every user of value_struct_elt will need to be updated, and as this commit already contains a bug fix, I wanted to keep the large refactoring in a separate commit, so, check out the next commit for the use of gdb::optional. gdb/ChangeLog: PR gdb/27994 * eval.c (structop_base_operation::evaluate_funcall): Pass array_view instead of array to value_struct_elt. * valarith.c (value_user_defined_op): Likewise. * valops.c (typecmp): Change parameter type from array pointer to array_view. Update header comment, and update body accordingly. (search_struct_method): Likewise. (value_struct_elt): Likewise. * value.h (value_struct_elt): Update declaration. gdb/testsuite/ChangeLog: PR gdb/27994 * gdb.cp/method-call-in-c.cc (struct foo_type): Add operator+=, change initial value of var member variable. (main): Make use of foo_type's operator+=. * gdb.cp/method-call-in-c.exp: Test use of operator+=.
2021-06-22 17:17:53 +08:00
/* Evaluate the arguments. The '+ 1' here is to allow for the `this'
pointer we placed into vals[0]. */
for (int i = 0; i < args.size (); ++i)
vals[i + 1] = args[i]->evaluate_with_coercion (exp, noside);
gdb: fix regression in evaluate_funcall for non C++ like cases This regression, as it is exposed by the test added in this commit, first became noticable with this commit: commit d182f2797922a305fbd1ef6a483cc39a56b43e02 Date: Mon Mar 8 07:27:57 2021 -0700 Convert c-exp.y to use operations But, this commit only added converted the C expression parser to make use of code that was added in this commit: commit a00b7254fb614af557de7ae7cc0eb39a0ce0e408 Date: Mon Mar 8 07:27:57 2021 -0700 Implement function call operations And it was this second commit that actually introduced the bugs (there are two). In structop_base_operation::evaluate_funcall we build up an argument list in the vector vals. Later in this function the argument list might be passed to value_struct_elt. Prior to commit a00b7254fb614 the vals vector (or argvec as it used to be called) stored the value for the function callee in the argvec at index 0. This 'callee' value is what ends up being passed to evaluate_subexp_do_call, and represents the function to be called, the value contents are the address of the function, and the value type is the function signature. The remaining items held in the argvec were the values to pass to the function. For a non-static member function the `this' pointer would be at index 1 in the array. After commit a00b7254fb614 this callee value is now held in a separate variable, not the vals array. So, for non-static member functions, the `this' pointer is now at index 0, with any other arguments after that. What this means is that previous, when we called value_struct_elt we would pass the address of argvec[1] as this was the first argument. But now we should be passing the address of vals[0]. Unfortunately, we are still passing vals[1], effectively skipping the first argument. The second issue is that, prior to commit a00b7254fb614, the argvec array was NULL terminated. This is required as value_struct_elt calls search_struct_method, which calls typecmp, and typecmp requires that the array have a NULL at the end. After commit a00b7254fb614 this NULL has been lost, and we are therefore violating the API requirements of typecmp. This commit fixes both of these regressions. I also extended the header comments on search_struct_method and value_struct_elt to make it clearer that the array required a NULL marker at the end. You will notice in the test attached to this commit that I test calling a non-static member function, but not calling a static member function. The reason for this is that calling static member functions is currently broken due to a different bug. That will be fixed in a later patch in this series, at which time I'll add a test for calling a static member function. gdb/ChangeLog: PR gdb/27994 * eval.c (structop_base_operation::evaluate_funcall): Add a nullptr to the end of the args array, which should not be included in the argument array_view. Pass all the arguments through to value_struct_elt. * valops.c (search_struct_method): Update header comment. (value_struct_elt): Likewise. gdb/testsuite/ChangeLog: PR gdb/27994 * gdb.cp/method-call-in-c.cc: New file. * gdb.cp/method-call-in-c.exp: New file.
2021-06-22 06:33:11 +08:00
gdb: replace NULL terminated array with array_view After the previous commit, this commit updates the value_struct_elt function to take an array_view rather than a NULL terminated array of values. The requirement for a NULL terminated array of values actually stems from typecmp, so the change from an array to array_view needs to be propagated through to this function. While making this change I noticed that this fixes another bug, in value_x_binop and value_x_unop GDB creates an array of values which doesn't have a NULL at the end. An array_view of this array is passed to value_user_defined_op, which then unpacks the array_view and passed the raw array to value_struct_elt, but only if the language is not C++. As value_x_binop and value_x_unop can only request member functions with the names of C++ operators, then most of the time, assuming the inferior is not a C++ program, then GDB will not find a matching member function with the call to value_struct_elt, and so typecmp will never be called, and so, GDB will avoid undefined behaviour. However, it is worth remembering that, when GDB's language is set to "auto", the current language is selected based on the language of the current compilation unit. As C++ programs usually link against libc, which is written in C, then, if the inferior is stopped in libc GDB will set the language to C. And so, it is possible that we will end up using value_struct_elt to try and lookup, and match, a C++ operator. If this occurs then GDB will experience undefined behaviour. I have extended the test added in the previous commit to also cover this case. Finally, this commit changes the API from passing around a pointer to an array to passing around a pointer to an array_view. The reason for this is that we need to be able to distinguish between the cases where we call value_struct_elt with no arguments, i.e. we are looking up a struct member, but we either don't have the arguments we want to pass yet, or we don't expect there to be any need for GDB to use the argument types to resolve any overloading; and the second case where we call value_struct_elt looking for a function that takes no arguments, that is, the argument list is empty. NOTE: While writing this I realise that if we pass an array_view at all then it will always have at least one item in it, the `this' pointer for the object we are planning to call the method on. So we could, I guess, pass an empty array_view to indicate the case where we don't know anything about the arguments, and when the array_view is length 1 or more, it means we do have the arguments. However, though we could do this, I don't think this would be better, the length 0 vs length 1 difference seems a little too subtle, I think that there's a better solution... I think a better solution would be to wrap the array_view in a gdb::optional, this would make the whole, do we have an array view or not question explicit. I haven't done this as part of this commit as making that change is much more extensive, every user of value_struct_elt will need to be updated, and as this commit already contains a bug fix, I wanted to keep the large refactoring in a separate commit, so, check out the next commit for the use of gdb::optional. gdb/ChangeLog: PR gdb/27994 * eval.c (structop_base_operation::evaluate_funcall): Pass array_view instead of array to value_struct_elt. * valarith.c (value_user_defined_op): Likewise. * valops.c (typecmp): Change parameter type from array pointer to array_view. Update header comment, and update body accordingly. (search_struct_method): Likewise. (value_struct_elt): Likewise. * value.h (value_struct_elt): Update declaration. gdb/testsuite/ChangeLog: PR gdb/27994 * gdb.cp/method-call-in-c.cc (struct foo_type): Add operator+=, change initial value of var member variable. (main): Make use of foo_type's operator+=. * gdb.cp/method-call-in-c.exp: Test use of operator+=.
2021-06-22 17:17:53 +08:00
/* The array view includes the `this' pointer. */
gdb::array_view<value *> arg_view (vals);
int static_memfuncp;
value *callee;
const char *tstr = std::get<1> (m_storage).c_str ();
if (overload_resolution
&& exp->language_defn->la_language == language_cplus)
{
/* Language is C++, do some overload resolution before
evaluation. */
value *val0 = vals[0];
find_overload_match (arg_view, tstr, METHOD,
&val0, nullptr, &callee, nullptr,
&static_memfuncp, 0, noside);
vals[0] = val0;
}
else
/* Non-C++ case -- or no overload resolution. */
{
struct value *temp = vals[0];
gdb: use gdb::optional instead of passing a pointer to gdb::array_view Following on from the previous commit, this commit changes the API of value_struct_elt to take gdb::optional<gdb::array_view<value *>> instead of a pointer to the gdb::array_view. This makes the optional nature of the array_view parameter explicit. This commit is purely a refactoring commit, there should be no user visible change after this commit. I have deliberately kept this refactor separate from the previous two commits as this is a more extensive change, and I'm not 100% sure that using gdb::optional for the parameter type, instead of a pointer, is going to be to everyone's taste. If there's push back on this patch then this one can be dropped from the series. gdb/ChangeLog: * ada-lang.c (desc_bounds): Use '{}' instead of NULL to indicate an empty gdb::optional when calling value_struct_elt. (desc_data): Likewise. (desc_one_bound): Likewise. * eval.c (structop_base_operation::evaluate_funcall): Pass gdb::array_view, not a gdb::array_view* to value_struct_elt. (eval_op_structop_struct): Use '{}' instead of NULL to indicate an empty gdb::optional when calling value_struct_elt. (eval_op_structop_ptr): Likewise. * f-lang.c (fortran_structop_operation::evaluate): Likewise. * guile/scm-value.c (gdbscm_value_field): Likewise. * m2-lang.c (eval_op_m2_high): Likewise. (eval_op_m2_subscript): Likewise. * opencl-lang.c (opencl_structop_operation::evaluate): Likewise. * python/py-value.c (valpy_getitem): Likewise. * rust-lang.c (rust_val_print_str): Likewise. (rust_range): Likewise. (rust_subscript): Likewise. (eval_op_rust_structop): Likewise. (rust_aggregate_operation::evaluate): Likewise. * valarith.c (value_user_defined_op): Likewise. * valops.c (search_struct_method): Change parameter type, update function body accordingly, and update header comment. (value_struct_elt): Change parameter type, update function body accordingly. * value.h (value_struct_elt): Update declaration.
2021-06-23 02:27:53 +08:00
callee = value_struct_elt (&temp, arg_view, tstr,
&static_memfuncp,
op == STRUCTOP_STRUCT
? "structure" : "structure pointer");
/* value_struct_elt updates temp with the correct value of the
``this'' pointer if necessary, so modify it to reflect any
``this'' changes. */
vals[0] = value_from_longest (lookup_pointer_type (temp->type ()),
temp->address ()
+ temp->embedded_offset ());
}
/* Take out `this' if needed. */
if (static_memfuncp)
arg_view = arg_view.slice (1);
return evaluate_subexp_do_call (exp, noside, callee, arg_view,
nullptr, expect_type);
}
/* Helper for structop_base_operation::complete which recursively adds
field and method names from TYPE, a struct or union type, to the
OUTPUT list. PREFIX is prepended to each result. */
static void
add_struct_fields (struct type *type, completion_list &output,
const char *fieldname, int namelen, const char *prefix)
{
int i;
int computed_type_name = 0;
const char *type_name = NULL;
type = check_typedef (type);
for (i = 0; i < type->num_fields (); ++i)
{
if (i < TYPE_N_BASECLASSES (type))
add_struct_fields (TYPE_BASECLASS (type, i),
output, fieldname, namelen, prefix);
else if (type->field (i).name ())
{
if (type->field (i).name ()[0] != '\0')
{
if (! strncmp (type->field (i).name (),
fieldname, namelen))
output.emplace_back (concat (prefix, type->field (i).name (),
nullptr));
}
else if (type->field (i).type ()->code () == TYPE_CODE_UNION)
{
/* Recurse into anonymous unions. */
add_struct_fields (type->field (i).type (),
output, fieldname, namelen, prefix);
}
}
}
for (i = TYPE_NFN_FIELDS (type) - 1; i >= 0; --i)
{
const char *name = TYPE_FN_FIELDLIST_NAME (type, i);
if (name && ! strncmp (name, fieldname, namelen))
{
if (!computed_type_name)
{
type_name = type->name ();
computed_type_name = 1;
}
/* Omit constructors from the completion list. */
if (!type_name || strcmp (type_name, name))
output.emplace_back (concat (prefix, name, nullptr));
}
}
}
/* See expop.h. */
bool
structop_base_operation::complete (struct expression *exp,
completion_tracker &tracker,
const char *prefix)
{
const std::string &fieldname = std::get<1> (m_storage);
value *lhs = std::get<0> (m_storage)->evaluate (nullptr, exp,
EVAL_AVOID_SIDE_EFFECTS);
struct type *type = lhs->type ();
for (;;)
{
type = check_typedef (type);
if (!type->is_pointer_or_reference ())
break;
type = type->target_type ();
}
if (type->code () == TYPE_CODE_UNION
|| type->code () == TYPE_CODE_STRUCT)
{
completion_list result;
add_struct_fields (type, result, fieldname.c_str (),
fieldname.length (), prefix);
tracker.add_completions (std::move (result));
return true;
}
return false;
}
} /* namespace expr */
/* Return true if type is integral or reference to integral */
static bool
is_integral_or_integral_reference (struct type *type)
{
if (is_integral_type (type))
return true;
type = check_typedef (type);
return (type != nullptr
&& TYPE_IS_REFERENCE (type)
&& is_integral_type (type->target_type ()));
}
/* Helper function that implements the body of OP_SCOPE. */
struct value *
eval_op_scope (struct type *expect_type, struct expression *exp,
enum noside noside,
struct type *type, const char *string)
{
struct value *arg1 = value_aggregate_elt (type, string, expect_type,
0, noside);
if (arg1 == NULL)
error (_("There is no field named %s"), string);
return arg1;
}
/* Helper function that implements the body of OP_VAR_ENTRY_VALUE. */
struct value *
eval_op_var_entry_value (struct type *expect_type, struct expression *exp,
enum noside noside, symbol *sym)
{
if (noside == EVAL_AVOID_SIDE_EFFECTS)
return value::zero (sym->type (), not_lval);
const symbol_computed_ops *computed_ops = sym->computed_ops ();
if (computed_ops == nullptr
|| computed_ops->read_variable_at_entry == nullptr)
error (_("Symbol \"%s\" does not have any specific entry value"),
sym->print_name ());
frame_info_ptr frame = get_selected_frame (NULL);
return computed_ops->read_variable_at_entry (sym, frame);
}
/* Helper function that implements the body of OP_VAR_MSYM_VALUE. */
struct value *
eval_op_var_msym_value (struct type *expect_type, struct expression *exp,
enum noside noside, bool outermost_p,
bound_minimal_symbol msymbol)
{
value *val = evaluate_var_msym_value (noside, msymbol.objfile,
msymbol.minsym);
struct type *type = val->type ();
if (type->code () == TYPE_CODE_ERROR
&& (noside != EVAL_AVOID_SIDE_EFFECTS || !outermost_p))
error_unknown_type (msymbol.minsym->print_name ());
return val;
}
/* Helper function that implements the body of OP_FUNC_STATIC_VAR. */
struct value *
eval_op_func_static_var (struct type *expect_type, struct expression *exp,
enum noside noside,
value *func, const char *var)
{
CORE_ADDR addr = func->address ();
const block *blk = block_for_pc (addr);
struct block_symbol sym = lookup_symbol (var, blk, SEARCH_VAR_DOMAIN,
nullptr);
if (sym.symbol == NULL)
error (_("No symbol \"%s\" in specified context."), var);
return evaluate_var_value (noside, sym.block, sym.symbol);
}
/* Helper function that implements the body of OP_REGISTER. */
struct value *
eval_op_register (struct type *expect_type, struct expression *exp,
enum noside noside, const char *name)
{
int regno;
struct value *val;
regno = user_reg_map_name_to_regnum (exp->gdbarch,
name, strlen (name));
if (regno == -1)
error (_("Register $%s not available."), name);
/* In EVAL_AVOID_SIDE_EFFECTS mode, we only need to return
a value with the appropriate register type. Unfortunately,
we don't have easy access to the type of user registers.
So for these registers, we fetch the register value regardless
of the evaluation mode. */
if (noside == EVAL_AVOID_SIDE_EFFECTS
&& regno < gdbarch_num_cooked_regs (exp->gdbarch))
val = value::zero (register_type (exp->gdbarch, regno), not_lval);
else
2023-12-02 00:27:21 +08:00
val = value_of_register
(regno, get_next_frame_sentinel_okay (get_selected_frame ()));
if (val == NULL)
error (_("Value of register %s not available."), name);
else
return val;
}
namespace expr
{
value *
string_operation::evaluate (struct type *expect_type,
struct expression *exp,
enum noside noside)
{
const std::string &str = std::get<0> (m_storage);
struct type *type = language_string_char_type (exp->language_defn,
exp->gdbarch);
return value_string (str.c_str (), str.size (), type);
}
struct value *
ternop_slice_operation::evaluate (struct type *expect_type,
struct expression *exp,
enum noside noside)
{
struct value *array
= std::get<0> (m_storage)->evaluate (nullptr, exp, noside);
struct value *low
= std::get<1> (m_storage)->evaluate (nullptr, exp, noside);
struct value *upper
= std::get<2> (m_storage)->evaluate (nullptr, exp, noside);
int lowbound = value_as_long (low);
int upperbound = value_as_long (upper);
return value_slice (array, lowbound, upperbound - lowbound + 1);
}
} /* namespace expr */
/* Helper function that implements the body of OP_OBJC_SELECTOR. */
struct value *
eval_op_objc_selector (struct type *expect_type, struct expression *exp,
enum noside noside,
const char *sel)
{
struct type *selector_type = builtin_type (exp->gdbarch)->builtin_data_ptr;
return value_from_longest (selector_type,
lookup_child_selector (exp->gdbarch, sel));
}
/* A helper function for STRUCTOP_STRUCT. */
struct value *
eval_op_structop_struct (struct type *expect_type, struct expression *exp,
enum noside noside,
struct value *arg1, const char *string)
{
gdb: use gdb::optional instead of passing a pointer to gdb::array_view Following on from the previous commit, this commit changes the API of value_struct_elt to take gdb::optional<gdb::array_view<value *>> instead of a pointer to the gdb::array_view. This makes the optional nature of the array_view parameter explicit. This commit is purely a refactoring commit, there should be no user visible change after this commit. I have deliberately kept this refactor separate from the previous two commits as this is a more extensive change, and I'm not 100% sure that using gdb::optional for the parameter type, instead of a pointer, is going to be to everyone's taste. If there's push back on this patch then this one can be dropped from the series. gdb/ChangeLog: * ada-lang.c (desc_bounds): Use '{}' instead of NULL to indicate an empty gdb::optional when calling value_struct_elt. (desc_data): Likewise. (desc_one_bound): Likewise. * eval.c (structop_base_operation::evaluate_funcall): Pass gdb::array_view, not a gdb::array_view* to value_struct_elt. (eval_op_structop_struct): Use '{}' instead of NULL to indicate an empty gdb::optional when calling value_struct_elt. (eval_op_structop_ptr): Likewise. * f-lang.c (fortran_structop_operation::evaluate): Likewise. * guile/scm-value.c (gdbscm_value_field): Likewise. * m2-lang.c (eval_op_m2_high): Likewise. (eval_op_m2_subscript): Likewise. * opencl-lang.c (opencl_structop_operation::evaluate): Likewise. * python/py-value.c (valpy_getitem): Likewise. * rust-lang.c (rust_val_print_str): Likewise. (rust_range): Likewise. (rust_subscript): Likewise. (eval_op_rust_structop): Likewise. (rust_aggregate_operation::evaluate): Likewise. * valarith.c (value_user_defined_op): Likewise. * valops.c (search_struct_method): Change parameter type, update function body accordingly, and update header comment. (value_struct_elt): Change parameter type, update function body accordingly. * value.h (value_struct_elt): Update declaration.
2021-06-23 02:27:53 +08:00
struct value *arg3 = value_struct_elt (&arg1, {}, string,
NULL, "structure");
if (noside == EVAL_AVOID_SIDE_EFFECTS)
arg3 = value::zero (arg3->type (), arg3->lval ());
return arg3;
}
/* A helper function for STRUCTOP_PTR. */
struct value *
eval_op_structop_ptr (struct type *expect_type, struct expression *exp,
enum noside noside,
struct value *arg1, const char *string)
{
/* Check to see if operator '->' has been overloaded. If so replace
arg1 with the value returned by evaluating operator->(). */
while (unop_user_defined_p (STRUCTOP_PTR, arg1))
{
struct value *value = NULL;
try
{
value = value_x_unop (arg1, STRUCTOP_PTR, noside);
}
catch (const gdb_exception_error &except)
{
if (except.error == NOT_FOUND_ERROR)
break;
else
throw;
}
arg1 = value;
}
/* JYG: if print object is on we need to replace the base type
with rtti type in order to continue on with successful
lookup of member / method only available in the rtti type. */
{
struct type *arg_type = arg1->type ();
struct type *real_type;
int full, using_enc;
LONGEST top;
struct value_print_options opts;
get_user_print_options (&opts);
if (opts.objectprint && arg_type->target_type ()
&& (arg_type->target_type ()->code () == TYPE_CODE_STRUCT))
{
real_type = value_rtti_indirect_type (arg1, &full, &top,
&using_enc);
if (real_type)
arg1 = value_cast (real_type, arg1);
}
}
gdb: use gdb::optional instead of passing a pointer to gdb::array_view Following on from the previous commit, this commit changes the API of value_struct_elt to take gdb::optional<gdb::array_view<value *>> instead of a pointer to the gdb::array_view. This makes the optional nature of the array_view parameter explicit. This commit is purely a refactoring commit, there should be no user visible change after this commit. I have deliberately kept this refactor separate from the previous two commits as this is a more extensive change, and I'm not 100% sure that using gdb::optional for the parameter type, instead of a pointer, is going to be to everyone's taste. If there's push back on this patch then this one can be dropped from the series. gdb/ChangeLog: * ada-lang.c (desc_bounds): Use '{}' instead of NULL to indicate an empty gdb::optional when calling value_struct_elt. (desc_data): Likewise. (desc_one_bound): Likewise. * eval.c (structop_base_operation::evaluate_funcall): Pass gdb::array_view, not a gdb::array_view* to value_struct_elt. (eval_op_structop_struct): Use '{}' instead of NULL to indicate an empty gdb::optional when calling value_struct_elt. (eval_op_structop_ptr): Likewise. * f-lang.c (fortran_structop_operation::evaluate): Likewise. * guile/scm-value.c (gdbscm_value_field): Likewise. * m2-lang.c (eval_op_m2_high): Likewise. (eval_op_m2_subscript): Likewise. * opencl-lang.c (opencl_structop_operation::evaluate): Likewise. * python/py-value.c (valpy_getitem): Likewise. * rust-lang.c (rust_val_print_str): Likewise. (rust_range): Likewise. (rust_subscript): Likewise. (eval_op_rust_structop): Likewise. (rust_aggregate_operation::evaluate): Likewise. * valarith.c (value_user_defined_op): Likewise. * valops.c (search_struct_method): Change parameter type, update function body accordingly, and update header comment. (value_struct_elt): Change parameter type, update function body accordingly. * value.h (value_struct_elt): Update declaration.
2021-06-23 02:27:53 +08:00
struct value *arg3 = value_struct_elt (&arg1, {}, string,
NULL, "structure pointer");
if (noside == EVAL_AVOID_SIDE_EFFECTS)
arg3 = value::zero (arg3->type (), arg3->lval ());
return arg3;
}
/* A helper function for STRUCTOP_MEMBER. */
struct value *
eval_op_member (struct type *expect_type, struct expression *exp,
enum noside noside,
struct value *arg1, struct value *arg2)
{
long mem_offset;
struct value *arg3;
struct type *type = check_typedef (arg2->type ());
switch (type->code ())
{
case TYPE_CODE_METHODPTR:
if (noside == EVAL_AVOID_SIDE_EFFECTS)
return value::zero (type->target_type (), not_lval);
else
{
arg2 = cplus_method_ptr_to_value (&arg1, arg2);
gdb_assert (arg2->type ()->code () == TYPE_CODE_PTR);
return value_ind (arg2);
}
case TYPE_CODE_MEMBERPTR:
/* Now, convert these values to an address. */
if (check_typedef (arg1->type ())->code () != TYPE_CODE_PTR)
arg1 = value_addr (arg1);
arg1 = value_cast_pointers (lookup_pointer_type (TYPE_SELF_TYPE (type)),
arg1, 1);
mem_offset = value_as_long (arg2);
arg3 = value_from_pointer (lookup_pointer_type (type->target_type ()),
value_as_long (arg1) + mem_offset);
return value_ind (arg3);
default:
error (_("non-pointer-to-member value used "
"in pointer-to-member construct"));
}
}
/* A helper function for BINOP_ADD. */
struct value *
eval_op_add (struct type *expect_type, struct expression *exp,
enum noside noside,
struct value *arg1, struct value *arg2)
{
if (binop_user_defined_p (BINOP_ADD, arg1, arg2))
return value_x_binop (arg1, arg2, BINOP_ADD, OP_NULL, noside);
else if (ptrmath_type_p (exp->language_defn, arg1->type ())
&& is_integral_or_integral_reference (arg2->type ()))
return value_ptradd (arg1, value_as_long (arg2));
else if (ptrmath_type_p (exp->language_defn, arg2->type ())
&& is_integral_or_integral_reference (arg1->type ()))
return value_ptradd (arg2, value_as_long (arg1));
else
{
binop_promote (exp->language_defn, exp->gdbarch, &arg1, &arg2);
return value_binop (arg1, arg2, BINOP_ADD);
}
}
/* A helper function for BINOP_SUB. */
struct value *
eval_op_sub (struct type *expect_type, struct expression *exp,
enum noside noside,
struct value *arg1, struct value *arg2)
{
if (binop_user_defined_p (BINOP_SUB, arg1, arg2))
return value_x_binop (arg1, arg2, BINOP_SUB, OP_NULL, noside);
else if (ptrmath_type_p (exp->language_defn, arg1->type ())
&& ptrmath_type_p (exp->language_defn, arg2->type ()))
{
/* FIXME -- should be ptrdiff_t */
struct type *type = builtin_type (exp->gdbarch)->builtin_long;
return value_from_longest (type, value_ptrdiff (arg1, arg2));
}
else if (ptrmath_type_p (exp->language_defn, arg1->type ())
&& is_integral_or_integral_reference (arg2->type ()))
return value_ptradd (arg1, - value_as_long (arg2));
else
{
binop_promote (exp->language_defn, exp->gdbarch, &arg1, &arg2);
return value_binop (arg1, arg2, BINOP_SUB);
}
}
/* Helper function for several different binary operations. */
struct value *
eval_op_binary (struct type *expect_type, struct expression *exp,
enum noside noside, enum exp_opcode op,
struct value *arg1, struct value *arg2)
{
if (binop_user_defined_p (op, arg1, arg2))
return value_x_binop (arg1, arg2, op, OP_NULL, noside);
else
{
/* If EVAL_AVOID_SIDE_EFFECTS and we're dividing by zero,
fudge arg2 to avoid division-by-zero, the caller is
(theoretically) only looking for the type of the result. */
if (noside == EVAL_AVOID_SIDE_EFFECTS
/* ??? Do we really want to test for BINOP_MOD here?
The implementation of value_binop gives it a well-defined
value. */
&& (op == BINOP_DIV
|| op == BINOP_INTDIV
|| op == BINOP_REM
|| op == BINOP_MOD)
&& value_logical_not (arg2))
{
struct value *v_one;
v_one = value_one (arg2->type ());
binop_promote (exp->language_defn, exp->gdbarch, &arg1, &v_one);
return value_binop (arg1, v_one, op);
}
else
{
/* For shift and integer exponentiation operations,
only promote the first argument. */
if ((op == BINOP_LSH || op == BINOP_RSH || op == BINOP_EXP)
&& is_integral_type (arg2->type ()))
unop_promote (exp->language_defn, exp->gdbarch, &arg1);
else
binop_promote (exp->language_defn, exp->gdbarch, &arg1, &arg2);
return value_binop (arg1, arg2, op);
}
}
}
/* A helper function for BINOP_SUBSCRIPT. */
struct value *
eval_op_subscript (struct type *expect_type, struct expression *exp,
enum noside noside, enum exp_opcode op,
struct value *arg1, struct value *arg2)
{
if (binop_user_defined_p (op, arg1, arg2))
return value_x_binop (arg1, arg2, op, OP_NULL, noside);
else
{
/* If the user attempts to subscript something that is not an
array or pointer type (like a plain int variable for example),
then report this as an error. */
arg1 = coerce_ref (arg1);
struct type *type = check_typedef (arg1->type ());
if (type->code () != TYPE_CODE_ARRAY
&& type->code () != TYPE_CODE_PTR)
{
if (type->name ())
error (_("cannot subscript something of type `%s'"),
type->name ());
else
error (_("cannot subscript requested type"));
}
if (noside == EVAL_AVOID_SIDE_EFFECTS)
return value::zero (type->target_type (), arg1->lval ());
else
return value_subscript (arg1, value_as_long (arg2));
}
}
/* A helper function for BINOP_EQUAL. */
struct value *
eval_op_equal (struct type *expect_type, struct expression *exp,
enum noside noside, enum exp_opcode op,
struct value *arg1, struct value *arg2)
{
if (binop_user_defined_p (op, arg1, arg2))
{
return value_x_binop (arg1, arg2, op, OP_NULL, noside);
}
else
{
binop_promote (exp->language_defn, exp->gdbarch, &arg1, &arg2);
int tem = value_equal (arg1, arg2);
struct type *type = language_bool_type (exp->language_defn,
exp->gdbarch);
return value_from_longest (type, (LONGEST) tem);
}
}
/* A helper function for BINOP_NOTEQUAL. */
struct value *
eval_op_notequal (struct type *expect_type, struct expression *exp,
enum noside noside, enum exp_opcode op,
struct value *arg1, struct value *arg2)
{
if (binop_user_defined_p (op, arg1, arg2))
{
return value_x_binop (arg1, arg2, op, OP_NULL, noside);
}
else
{
binop_promote (exp->language_defn, exp->gdbarch, &arg1, &arg2);
int tem = value_equal (arg1, arg2);
struct type *type = language_bool_type (exp->language_defn,
exp->gdbarch);
return value_from_longest (type, (LONGEST) ! tem);
}
}
/* A helper function for BINOP_LESS. */
struct value *
eval_op_less (struct type *expect_type, struct expression *exp,
enum noside noside, enum exp_opcode op,
struct value *arg1, struct value *arg2)
{
if (binop_user_defined_p (op, arg1, arg2))
{
return value_x_binop (arg1, arg2, op, OP_NULL, noside);
}
else
{
binop_promote (exp->language_defn, exp->gdbarch, &arg1, &arg2);
int tem = value_less (arg1, arg2);
struct type *type = language_bool_type (exp->language_defn,
exp->gdbarch);
return value_from_longest (type, (LONGEST) tem);
}
}
/* A helper function for BINOP_GTR. */
struct value *
eval_op_gtr (struct type *expect_type, struct expression *exp,
enum noside noside, enum exp_opcode op,
struct value *arg1, struct value *arg2)
{
if (binop_user_defined_p (op, arg1, arg2))
{
return value_x_binop (arg1, arg2, op, OP_NULL, noside);
}
else
{
binop_promote (exp->language_defn, exp->gdbarch, &arg1, &arg2);
int tem = value_less (arg2, arg1);
struct type *type = language_bool_type (exp->language_defn,
exp->gdbarch);
return value_from_longest (type, (LONGEST) tem);
}
}
/* A helper function for BINOP_GEQ. */
struct value *
eval_op_geq (struct type *expect_type, struct expression *exp,
enum noside noside, enum exp_opcode op,
struct value *arg1, struct value *arg2)
{
if (binop_user_defined_p (op, arg1, arg2))
{
return value_x_binop (arg1, arg2, op, OP_NULL, noside);
}
else
{
binop_promote (exp->language_defn, exp->gdbarch, &arg1, &arg2);
int tem = value_less (arg2, arg1) || value_equal (arg1, arg2);
struct type *type = language_bool_type (exp->language_defn,
exp->gdbarch);
return value_from_longest (type, (LONGEST) tem);
}
}
/* A helper function for BINOP_LEQ. */
struct value *
eval_op_leq (struct type *expect_type, struct expression *exp,
enum noside noside, enum exp_opcode op,
struct value *arg1, struct value *arg2)
{
if (binop_user_defined_p (op, arg1, arg2))
{
return value_x_binop (arg1, arg2, op, OP_NULL, noside);
}
else
{
binop_promote (exp->language_defn, exp->gdbarch, &arg1, &arg2);
int tem = value_less (arg1, arg2) || value_equal (arg1, arg2);
struct type *type = language_bool_type (exp->language_defn,
exp->gdbarch);
return value_from_longest (type, (LONGEST) tem);
}
}
/* A helper function for BINOP_REPEAT. */
struct value *
eval_op_repeat (struct type *expect_type, struct expression *exp,
enum noside noside, enum exp_opcode op,
struct value *arg1, struct value *arg2)
{
struct type *type = check_typedef (arg2->type ());
if (type->code () != TYPE_CODE_INT
&& type->code () != TYPE_CODE_ENUM)
error (_("Non-integral right operand for \"@\" operator."));
if (noside == EVAL_AVOID_SIDE_EFFECTS)
{
return allocate_repeat_value (arg1->type (),
longest_to_int (value_as_long (arg2)));
}
else
return value_repeat (arg1, longest_to_int (value_as_long (arg2)));
}
/* A helper function for UNOP_PLUS. */
struct value *
eval_op_plus (struct type *expect_type, struct expression *exp,
enum noside noside, enum exp_opcode op,
struct value *arg1)
{
if (unop_user_defined_p (op, arg1))
return value_x_unop (arg1, op, noside);
else
{
unop_promote (exp->language_defn, exp->gdbarch, &arg1);
return value_pos (arg1);
}
}
/* A helper function for UNOP_NEG. */
struct value *
eval_op_neg (struct type *expect_type, struct expression *exp,
enum noside noside, enum exp_opcode op,
struct value *arg1)
{
if (unop_user_defined_p (op, arg1))
return value_x_unop (arg1, op, noside);
else
{
unop_promote (exp->language_defn, exp->gdbarch, &arg1);
return value_neg (arg1);
}
}
/* A helper function for UNOP_COMPLEMENT. */
struct value *
eval_op_complement (struct type *expect_type, struct expression *exp,
enum noside noside, enum exp_opcode op,
struct value *arg1)
{
if (unop_user_defined_p (UNOP_COMPLEMENT, arg1))
return value_x_unop (arg1, UNOP_COMPLEMENT, noside);
else
{
unop_promote (exp->language_defn, exp->gdbarch, &arg1);
return value_complement (arg1);
}
}
/* A helper function for UNOP_LOGICAL_NOT. */
struct value *
eval_op_lognot (struct type *expect_type, struct expression *exp,
enum noside noside, enum exp_opcode op,
struct value *arg1)
{
if (unop_user_defined_p (op, arg1))
return value_x_unop (arg1, op, noside);
else
{
struct type *type = language_bool_type (exp->language_defn,
exp->gdbarch);
return value_from_longest (type, (LONGEST) value_logical_not (arg1));
}
}
/* A helper function for UNOP_IND. */
struct value *
eval_op_ind (struct type *expect_type, struct expression *exp,
enum noside noside,
struct value *arg1)
{
struct type *type = check_typedef (arg1->type ());
if (type->code () == TYPE_CODE_METHODPTR
|| type->code () == TYPE_CODE_MEMBERPTR)
error (_("Attempt to dereference pointer "
"to member without an object"));
if (unop_user_defined_p (UNOP_IND, arg1))
return value_x_unop (arg1, UNOP_IND, noside);
else if (noside == EVAL_AVOID_SIDE_EFFECTS)
{
type = check_typedef (arg1->type ());
/* If the type pointed to is dynamic then in order to resolve the
dynamic properties we must actually dereference the pointer.
There is a risk that this dereference will have side-effects
in the inferior, but being able to print accurate type
information seems worth the risk. */
if (!type->is_pointer_or_reference ()
|| !is_dynamic_type (type->target_type ()))
{
if (type->is_pointer_or_reference ()
/* In C you can dereference an array to get the 1st elt. */
|| type->code () == TYPE_CODE_ARRAY)
return value::zero (type->target_type (),
lval_memory);
else if (type->code () == TYPE_CODE_INT)
/* GDB allows dereferencing an int. */
return value::zero (builtin_type (exp->gdbarch)->builtin_int,
lval_memory);
else
error (_("Attempt to take contents of a non-pointer value."));
}
}
/* Allow * on an integer so we can cast it to whatever we want.
This returns an int, which seems like the most C-like thing to
do. "long long" variables are rare enough that
BUILTIN_TYPE_LONGEST would seem to be a mistake. */
if (type->code () == TYPE_CODE_INT)
return value_at_lazy (builtin_type (exp->gdbarch)->builtin_int,
value_as_address (arg1));
return value_ind (arg1);
}
/* A helper function for UNOP_ALIGNOF. */
struct value *
eval_op_alignof (struct type *expect_type, struct expression *exp,
enum noside noside,
struct value *arg1)
{
struct type *type = arg1->type ();
/* FIXME: This should be size_t. */
struct type *size_type = builtin_type (exp->gdbarch)->builtin_int;
ULONGEST align = type_align (type);
if (align == 0)
error (_("could not determine alignment of type"));
return value_from_longest (size_type, align);
}
/* A helper function for UNOP_MEMVAL. */
struct value *
eval_op_memval (struct type *expect_type, struct expression *exp,
enum noside noside,
struct value *arg1, struct type *type)
{
if (noside == EVAL_AVOID_SIDE_EFFECTS)
return value::zero (type, lval_memory);
else
return value_at_lazy (type, value_as_address (arg1));
}
/* A helper function for UNOP_PREINCREMENT. */
struct value *
eval_op_preinc (struct type *expect_type, struct expression *exp,
enum noside noside, enum exp_opcode op,
struct value *arg1)
{
Remove EVAL_SKIP EVAL_SKIP was needed in the old expression implementation due to its linearized tree structure. This is not needed in the new implementation, because it is trivial to not evaluate a subexpression. This patch removes the last vestiges of EVAL_SKIP. gdb/ChangeLog 2021-03-08 Tom Tromey <tom@tromey.com> * value.h (eval_skip_value): Don't declare. * opencl-lang.c (eval_opencl_assign): Update. * m2-lang.c (eval_op_m2_high, eval_op_m2_subscript): Update. * f-lang.c (eval_op_f_abs, eval_op_f_mod, eval_op_f_ceil) (eval_op_f_floor, eval_op_f_modulo, eval_op_f_cmplx): Remove. * expression.h (enum noside) <EVAL_SKIP>: Remove. * expop.h (typeof_operation::evaluate) (decltype_operation::evaluate, unop_addr_operation::evaluate) (unop_sizeof_operation::evaluate, assign_operation::evaluate) (cxx_cast_operation::evaluate): Update. * eval.c (eval_skip_value): Remove. (eval_op_scope, eval_op_var_entry_value) (eval_op_func_static_var, eval_op_string, eval_op_objc_selector) (eval_op_concat, eval_op_ternop, eval_op_structop_struct) (eval_op_structop_ptr, eval_op_member, eval_op_add, eval_op_sub) (eval_op_binary, eval_op_subscript, eval_op_equal) (eval_op_notequal, eval_op_less, eval_op_gtr, eval_op_geq) (eval_op_leq, eval_op_repeat, eval_op_plus, eval_op_neg) (eval_op_complement, eval_op_lognot, eval_op_ind) (eval_op_memval, eval_op_preinc, eval_op_predec) (eval_op_postinc, eval_op_postdec, eval_op_type) (eval_binop_assign_modify, eval_op_objc_msgcall) (eval_multi_subscript, logical_and_operation::evaluate) (logical_or_operation::evaluate, array_operation::evaluate) (operation::evaluate_for_cast) (var_msym_value_operation::evaluate_for_cast) (var_value_operation::evaluate_for_cast): Update. * c-lang.c (c_string_operation::evaluate): Update. * c-exp.h (objc_nsstring_operation::evaluate) (objc_selector_operation::evaluate): Update. * ada-lang.c (ada_assign_operation::evaluate) (eval_ternop_in_range, ada_unop_neg, ada_unop_in_range) (ada_atr_size): Update.
2021-03-08 22:27:57 +08:00
if (noside == EVAL_AVOID_SIDE_EFFECTS)
return arg1;
else if (unop_user_defined_p (op, arg1))
{
return value_x_unop (arg1, op, noside);
}
else
{
struct value *arg2;
if (ptrmath_type_p (exp->language_defn, arg1->type ()))
arg2 = value_ptradd (arg1, 1);
else
{
struct value *tmp = arg1;
arg2 = value_one (arg1->type ());
binop_promote (exp->language_defn, exp->gdbarch, &tmp, &arg2);
arg2 = value_binop (tmp, arg2, BINOP_ADD);
}
return value_assign (arg1, arg2);
}
}
/* A helper function for UNOP_PREDECREMENT. */
struct value *
eval_op_predec (struct type *expect_type, struct expression *exp,
enum noside noside, enum exp_opcode op,
struct value *arg1)
{
Remove EVAL_SKIP EVAL_SKIP was needed in the old expression implementation due to its linearized tree structure. This is not needed in the new implementation, because it is trivial to not evaluate a subexpression. This patch removes the last vestiges of EVAL_SKIP. gdb/ChangeLog 2021-03-08 Tom Tromey <tom@tromey.com> * value.h (eval_skip_value): Don't declare. * opencl-lang.c (eval_opencl_assign): Update. * m2-lang.c (eval_op_m2_high, eval_op_m2_subscript): Update. * f-lang.c (eval_op_f_abs, eval_op_f_mod, eval_op_f_ceil) (eval_op_f_floor, eval_op_f_modulo, eval_op_f_cmplx): Remove. * expression.h (enum noside) <EVAL_SKIP>: Remove. * expop.h (typeof_operation::evaluate) (decltype_operation::evaluate, unop_addr_operation::evaluate) (unop_sizeof_operation::evaluate, assign_operation::evaluate) (cxx_cast_operation::evaluate): Update. * eval.c (eval_skip_value): Remove. (eval_op_scope, eval_op_var_entry_value) (eval_op_func_static_var, eval_op_string, eval_op_objc_selector) (eval_op_concat, eval_op_ternop, eval_op_structop_struct) (eval_op_structop_ptr, eval_op_member, eval_op_add, eval_op_sub) (eval_op_binary, eval_op_subscript, eval_op_equal) (eval_op_notequal, eval_op_less, eval_op_gtr, eval_op_geq) (eval_op_leq, eval_op_repeat, eval_op_plus, eval_op_neg) (eval_op_complement, eval_op_lognot, eval_op_ind) (eval_op_memval, eval_op_preinc, eval_op_predec) (eval_op_postinc, eval_op_postdec, eval_op_type) (eval_binop_assign_modify, eval_op_objc_msgcall) (eval_multi_subscript, logical_and_operation::evaluate) (logical_or_operation::evaluate, array_operation::evaluate) (operation::evaluate_for_cast) (var_msym_value_operation::evaluate_for_cast) (var_value_operation::evaluate_for_cast): Update. * c-lang.c (c_string_operation::evaluate): Update. * c-exp.h (objc_nsstring_operation::evaluate) (objc_selector_operation::evaluate): Update. * ada-lang.c (ada_assign_operation::evaluate) (eval_ternop_in_range, ada_unop_neg, ada_unop_in_range) (ada_atr_size): Update.
2021-03-08 22:27:57 +08:00
if (noside == EVAL_AVOID_SIDE_EFFECTS)
return arg1;
else if (unop_user_defined_p (op, arg1))
{
return value_x_unop (arg1, op, noside);
}
else
{
struct value *arg2;
if (ptrmath_type_p (exp->language_defn, arg1->type ()))
arg2 = value_ptradd (arg1, -1);
else
{
struct value *tmp = arg1;
arg2 = value_one (arg1->type ());
binop_promote (exp->language_defn, exp->gdbarch, &tmp, &arg2);
arg2 = value_binop (tmp, arg2, BINOP_SUB);
}
return value_assign (arg1, arg2);
}
}
/* A helper function for UNOP_POSTINCREMENT. */
struct value *
eval_op_postinc (struct type *expect_type, struct expression *exp,
enum noside noside, enum exp_opcode op,
struct value *arg1)
{
Remove EVAL_SKIP EVAL_SKIP was needed in the old expression implementation due to its linearized tree structure. This is not needed in the new implementation, because it is trivial to not evaluate a subexpression. This patch removes the last vestiges of EVAL_SKIP. gdb/ChangeLog 2021-03-08 Tom Tromey <tom@tromey.com> * value.h (eval_skip_value): Don't declare. * opencl-lang.c (eval_opencl_assign): Update. * m2-lang.c (eval_op_m2_high, eval_op_m2_subscript): Update. * f-lang.c (eval_op_f_abs, eval_op_f_mod, eval_op_f_ceil) (eval_op_f_floor, eval_op_f_modulo, eval_op_f_cmplx): Remove. * expression.h (enum noside) <EVAL_SKIP>: Remove. * expop.h (typeof_operation::evaluate) (decltype_operation::evaluate, unop_addr_operation::evaluate) (unop_sizeof_operation::evaluate, assign_operation::evaluate) (cxx_cast_operation::evaluate): Update. * eval.c (eval_skip_value): Remove. (eval_op_scope, eval_op_var_entry_value) (eval_op_func_static_var, eval_op_string, eval_op_objc_selector) (eval_op_concat, eval_op_ternop, eval_op_structop_struct) (eval_op_structop_ptr, eval_op_member, eval_op_add, eval_op_sub) (eval_op_binary, eval_op_subscript, eval_op_equal) (eval_op_notequal, eval_op_less, eval_op_gtr, eval_op_geq) (eval_op_leq, eval_op_repeat, eval_op_plus, eval_op_neg) (eval_op_complement, eval_op_lognot, eval_op_ind) (eval_op_memval, eval_op_preinc, eval_op_predec) (eval_op_postinc, eval_op_postdec, eval_op_type) (eval_binop_assign_modify, eval_op_objc_msgcall) (eval_multi_subscript, logical_and_operation::evaluate) (logical_or_operation::evaluate, array_operation::evaluate) (operation::evaluate_for_cast) (var_msym_value_operation::evaluate_for_cast) (var_value_operation::evaluate_for_cast): Update. * c-lang.c (c_string_operation::evaluate): Update. * c-exp.h (objc_nsstring_operation::evaluate) (objc_selector_operation::evaluate): Update. * ada-lang.c (ada_assign_operation::evaluate) (eval_ternop_in_range, ada_unop_neg, ada_unop_in_range) (ada_atr_size): Update.
2021-03-08 22:27:57 +08:00
if (noside == EVAL_AVOID_SIDE_EFFECTS)
return arg1;
else if (unop_user_defined_p (op, arg1))
{
return value_x_unop (arg1, op, noside);
}
else
{
struct value *arg3 = arg1->non_lval ();
struct value *arg2;
if (ptrmath_type_p (exp->language_defn, arg1->type ()))
arg2 = value_ptradd (arg1, 1);
else
{
struct value *tmp = arg1;
arg2 = value_one (arg1->type ());
binop_promote (exp->language_defn, exp->gdbarch, &tmp, &arg2);
arg2 = value_binop (tmp, arg2, BINOP_ADD);
}
value_assign (arg1, arg2);
return arg3;
}
}
/* A helper function for UNOP_POSTDECREMENT. */
struct value *
eval_op_postdec (struct type *expect_type, struct expression *exp,
enum noside noside, enum exp_opcode op,
struct value *arg1)
{
Remove EVAL_SKIP EVAL_SKIP was needed in the old expression implementation due to its linearized tree structure. This is not needed in the new implementation, because it is trivial to not evaluate a subexpression. This patch removes the last vestiges of EVAL_SKIP. gdb/ChangeLog 2021-03-08 Tom Tromey <tom@tromey.com> * value.h (eval_skip_value): Don't declare. * opencl-lang.c (eval_opencl_assign): Update. * m2-lang.c (eval_op_m2_high, eval_op_m2_subscript): Update. * f-lang.c (eval_op_f_abs, eval_op_f_mod, eval_op_f_ceil) (eval_op_f_floor, eval_op_f_modulo, eval_op_f_cmplx): Remove. * expression.h (enum noside) <EVAL_SKIP>: Remove. * expop.h (typeof_operation::evaluate) (decltype_operation::evaluate, unop_addr_operation::evaluate) (unop_sizeof_operation::evaluate, assign_operation::evaluate) (cxx_cast_operation::evaluate): Update. * eval.c (eval_skip_value): Remove. (eval_op_scope, eval_op_var_entry_value) (eval_op_func_static_var, eval_op_string, eval_op_objc_selector) (eval_op_concat, eval_op_ternop, eval_op_structop_struct) (eval_op_structop_ptr, eval_op_member, eval_op_add, eval_op_sub) (eval_op_binary, eval_op_subscript, eval_op_equal) (eval_op_notequal, eval_op_less, eval_op_gtr, eval_op_geq) (eval_op_leq, eval_op_repeat, eval_op_plus, eval_op_neg) (eval_op_complement, eval_op_lognot, eval_op_ind) (eval_op_memval, eval_op_preinc, eval_op_predec) (eval_op_postinc, eval_op_postdec, eval_op_type) (eval_binop_assign_modify, eval_op_objc_msgcall) (eval_multi_subscript, logical_and_operation::evaluate) (logical_or_operation::evaluate, array_operation::evaluate) (operation::evaluate_for_cast) (var_msym_value_operation::evaluate_for_cast) (var_value_operation::evaluate_for_cast): Update. * c-lang.c (c_string_operation::evaluate): Update. * c-exp.h (objc_nsstring_operation::evaluate) (objc_selector_operation::evaluate): Update. * ada-lang.c (ada_assign_operation::evaluate) (eval_ternop_in_range, ada_unop_neg, ada_unop_in_range) (ada_atr_size): Update.
2021-03-08 22:27:57 +08:00
if (noside == EVAL_AVOID_SIDE_EFFECTS)
return arg1;
else if (unop_user_defined_p (op, arg1))
{
return value_x_unop (arg1, op, noside);
}
else
{
struct value *arg3 = arg1->non_lval ();
struct value *arg2;
if (ptrmath_type_p (exp->language_defn, arg1->type ()))
arg2 = value_ptradd (arg1, -1);
else
{
struct value *tmp = arg1;
arg2 = value_one (arg1->type ());
binop_promote (exp->language_defn, exp->gdbarch, &tmp, &arg2);
arg2 = value_binop (tmp, arg2, BINOP_SUB);
}
value_assign (arg1, arg2);
return arg3;
}
}
/* A helper function for OP_TYPE. */
struct value *
eval_op_type (struct type *expect_type, struct expression *exp,
enum noside noside, struct type *type)
{
Remove EVAL_SKIP EVAL_SKIP was needed in the old expression implementation due to its linearized tree structure. This is not needed in the new implementation, because it is trivial to not evaluate a subexpression. This patch removes the last vestiges of EVAL_SKIP. gdb/ChangeLog 2021-03-08 Tom Tromey <tom@tromey.com> * value.h (eval_skip_value): Don't declare. * opencl-lang.c (eval_opencl_assign): Update. * m2-lang.c (eval_op_m2_high, eval_op_m2_subscript): Update. * f-lang.c (eval_op_f_abs, eval_op_f_mod, eval_op_f_ceil) (eval_op_f_floor, eval_op_f_modulo, eval_op_f_cmplx): Remove. * expression.h (enum noside) <EVAL_SKIP>: Remove. * expop.h (typeof_operation::evaluate) (decltype_operation::evaluate, unop_addr_operation::evaluate) (unop_sizeof_operation::evaluate, assign_operation::evaluate) (cxx_cast_operation::evaluate): Update. * eval.c (eval_skip_value): Remove. (eval_op_scope, eval_op_var_entry_value) (eval_op_func_static_var, eval_op_string, eval_op_objc_selector) (eval_op_concat, eval_op_ternop, eval_op_structop_struct) (eval_op_structop_ptr, eval_op_member, eval_op_add, eval_op_sub) (eval_op_binary, eval_op_subscript, eval_op_equal) (eval_op_notequal, eval_op_less, eval_op_gtr, eval_op_geq) (eval_op_leq, eval_op_repeat, eval_op_plus, eval_op_neg) (eval_op_complement, eval_op_lognot, eval_op_ind) (eval_op_memval, eval_op_preinc, eval_op_predec) (eval_op_postinc, eval_op_postdec, eval_op_type) (eval_binop_assign_modify, eval_op_objc_msgcall) (eval_multi_subscript, logical_and_operation::evaluate) (logical_or_operation::evaluate, array_operation::evaluate) (operation::evaluate_for_cast) (var_msym_value_operation::evaluate_for_cast) (var_value_operation::evaluate_for_cast): Update. * c-lang.c (c_string_operation::evaluate): Update. * c-exp.h (objc_nsstring_operation::evaluate) (objc_selector_operation::evaluate): Update. * ada-lang.c (ada_assign_operation::evaluate) (eval_ternop_in_range, ada_unop_neg, ada_unop_in_range) (ada_atr_size): Update.
2021-03-08 22:27:57 +08:00
if (noside == EVAL_AVOID_SIDE_EFFECTS)
return value::allocate (type);
else
error (_("Attempt to use a type name as an expression"));
}
/* A helper function for BINOP_ASSIGN_MODIFY. */
struct value *
eval_binop_assign_modify (struct type *expect_type, struct expression *exp,
enum noside noside, enum exp_opcode op,
struct value *arg1, struct value *arg2)
{
Remove EVAL_SKIP EVAL_SKIP was needed in the old expression implementation due to its linearized tree structure. This is not needed in the new implementation, because it is trivial to not evaluate a subexpression. This patch removes the last vestiges of EVAL_SKIP. gdb/ChangeLog 2021-03-08 Tom Tromey <tom@tromey.com> * value.h (eval_skip_value): Don't declare. * opencl-lang.c (eval_opencl_assign): Update. * m2-lang.c (eval_op_m2_high, eval_op_m2_subscript): Update. * f-lang.c (eval_op_f_abs, eval_op_f_mod, eval_op_f_ceil) (eval_op_f_floor, eval_op_f_modulo, eval_op_f_cmplx): Remove. * expression.h (enum noside) <EVAL_SKIP>: Remove. * expop.h (typeof_operation::evaluate) (decltype_operation::evaluate, unop_addr_operation::evaluate) (unop_sizeof_operation::evaluate, assign_operation::evaluate) (cxx_cast_operation::evaluate): Update. * eval.c (eval_skip_value): Remove. (eval_op_scope, eval_op_var_entry_value) (eval_op_func_static_var, eval_op_string, eval_op_objc_selector) (eval_op_concat, eval_op_ternop, eval_op_structop_struct) (eval_op_structop_ptr, eval_op_member, eval_op_add, eval_op_sub) (eval_op_binary, eval_op_subscript, eval_op_equal) (eval_op_notequal, eval_op_less, eval_op_gtr, eval_op_geq) (eval_op_leq, eval_op_repeat, eval_op_plus, eval_op_neg) (eval_op_complement, eval_op_lognot, eval_op_ind) (eval_op_memval, eval_op_preinc, eval_op_predec) (eval_op_postinc, eval_op_postdec, eval_op_type) (eval_binop_assign_modify, eval_op_objc_msgcall) (eval_multi_subscript, logical_and_operation::evaluate) (logical_or_operation::evaluate, array_operation::evaluate) (operation::evaluate_for_cast) (var_msym_value_operation::evaluate_for_cast) (var_value_operation::evaluate_for_cast): Update. * c-lang.c (c_string_operation::evaluate): Update. * c-exp.h (objc_nsstring_operation::evaluate) (objc_selector_operation::evaluate): Update. * ada-lang.c (ada_assign_operation::evaluate) (eval_ternop_in_range, ada_unop_neg, ada_unop_in_range) (ada_atr_size): Update.
2021-03-08 22:27:57 +08:00
if (noside == EVAL_AVOID_SIDE_EFFECTS)
return arg1;
if (binop_user_defined_p (op, arg1, arg2))
return value_x_binop (arg1, arg2, BINOP_ASSIGN_MODIFY, op, noside);
else if (op == BINOP_ADD && ptrmath_type_p (exp->language_defn,
arg1->type ())
&& is_integral_type (arg2->type ()))
arg2 = value_ptradd (arg1, value_as_long (arg2));
else if (op == BINOP_SUB && ptrmath_type_p (exp->language_defn,
arg1->type ())
&& is_integral_type (arg2->type ()))
arg2 = value_ptradd (arg1, - value_as_long (arg2));
else
{
struct value *tmp = arg1;
/* For shift and integer exponentiation operations,
only promote the first argument. */
if ((op == BINOP_LSH || op == BINOP_RSH || op == BINOP_EXP)
&& is_integral_type (arg2->type ()))
unop_promote (exp->language_defn, exp->gdbarch, &tmp);
else
binop_promote (exp->language_defn, exp->gdbarch, &tmp, &arg2);
arg2 = value_binop (tmp, arg2, op);
}
return value_assign (arg1, arg2);
}
/* Note that ARGS needs 2 empty slots up front and must end with a
null pointer. */
static struct value *
eval_op_objc_msgcall (struct type *expect_type, struct expression *exp,
enum noside noside, CORE_ADDR selector,
value *target, gdb::array_view<value *> args)
{
CORE_ADDR responds_selector = 0;
CORE_ADDR method_selector = 0;
int struct_return = 0;
struct value *msg_send = NULL;
struct value *msg_send_stret = NULL;
int gnu_runtime = 0;
struct value *method = NULL;
struct value *called_method = NULL;
struct type *selector_type = NULL;
struct type *long_type;
struct type *type;
struct value *ret = NULL;
CORE_ADDR addr = 0;
value *argvec[5];
long_type = builtin_type (exp->gdbarch)->builtin_long;
selector_type = builtin_type (exp->gdbarch)->builtin_data_ptr;
if (value_as_long (target) == 0)
return value_from_longest (long_type, 0);
if (lookup_minimal_symbol (current_program_space, "objc_msg_lookup").minsym
!= nullptr)
gnu_runtime = 1;
/* Find the method dispatch (Apple runtime) or method lookup
(GNU runtime) function for Objective-C. These will be used
to lookup the symbol information for the method. If we
can't find any symbol information, then we'll use these to
call the method, otherwise we can call the method
directly. The msg_send_stret function is used in the special
case of a method that returns a structure (Apple runtime
only). */
if (gnu_runtime)
{
type = selector_type;
type = lookup_function_type (type);
type = lookup_pointer_type (type);
type = lookup_function_type (type);
type = lookup_pointer_type (type);
msg_send = find_function_in_inferior ("objc_msg_lookup", NULL);
msg_send_stret
= find_function_in_inferior ("objc_msg_lookup", NULL);
msg_send = value_from_pointer (type, value_as_address (msg_send));
msg_send_stret = value_from_pointer (type,
value_as_address (msg_send_stret));
}
else
{
msg_send = find_function_in_inferior ("objc_msgSend", NULL);
/* Special dispatcher for methods returning structs. */
msg_send_stret
= find_function_in_inferior ("objc_msgSend_stret", NULL);
}
/* Verify the target object responds to this method. The
standard top-level 'Object' class uses a different name for
the verification method than the non-standard, but more
often used, 'NSObject' class. Make sure we check for both. */
responds_selector
= lookup_child_selector (exp->gdbarch, "respondsToSelector:");
if (responds_selector == 0)
responds_selector
= lookup_child_selector (exp->gdbarch, "respondsTo:");
if (responds_selector == 0)
error (_("no 'respondsTo:' or 'respondsToSelector:' method"));
method_selector
= lookup_child_selector (exp->gdbarch, "methodForSelector:");
if (method_selector == 0)
method_selector
= lookup_child_selector (exp->gdbarch, "methodFor:");
if (method_selector == 0)
error (_("no 'methodFor:' or 'methodForSelector:' method"));
/* Call the verification method, to make sure that the target
class implements the desired method. */
argvec[0] = msg_send;
argvec[1] = target;
argvec[2] = value_from_longest (long_type, responds_selector);
argvec[3] = value_from_longest (long_type, selector);
argvec[4] = 0;
ret = call_function_by_hand (argvec[0], NULL, {argvec + 1, 3});
if (gnu_runtime)
{
/* Function objc_msg_lookup returns a pointer. */
argvec[0] = ret;
ret = call_function_by_hand (argvec[0], NULL, {argvec + 1, 3});
}
if (value_as_long (ret) == 0)
error (_("Target does not respond to this message selector."));
/* Call "methodForSelector:" method, to get the address of a
function method that implements this selector for this
class. If we can find a symbol at that address, then we
know the return type, parameter types etc. (that's a good
thing). */
argvec[0] = msg_send;
argvec[1] = target;
argvec[2] = value_from_longest (long_type, method_selector);
argvec[3] = value_from_longest (long_type, selector);
argvec[4] = 0;
ret = call_function_by_hand (argvec[0], NULL, {argvec + 1, 3});
if (gnu_runtime)
{
argvec[0] = ret;
ret = call_function_by_hand (argvec[0], NULL, {argvec + 1, 3});
}
/* ret should now be the selector. */
addr = value_as_long (ret);
if (addr)
{
struct symbol *sym = NULL;
/* The address might point to a function descriptor;
resolve it to the actual code address instead. */
addr = gdbarch_convert_from_func_ptr_addr
(exp->gdbarch, addr, current_inferior ()->top_target ());
/* Is it a high_level symbol? */
sym = find_pc_function (addr);
if (sym != NULL)
method = value_of_variable (sym, 0);
}
/* If we found a method with symbol information, check to see
if it returns a struct. Otherwise assume it doesn't. */
if (method)
{
CORE_ADDR funaddr;
struct type *val_type;
funaddr = find_function_addr (method, &val_type);
block_for_pc (funaddr);
val_type = check_typedef (val_type);
if ((val_type == NULL)
|| (val_type->code () == TYPE_CODE_ERROR))
{
if (expect_type != NULL)
val_type = expect_type;
}
struct_return = using_struct_return (exp->gdbarch, method,
val_type);
}
else if (expect_type != NULL)
{
struct_return = using_struct_return (exp->gdbarch, NULL,
check_typedef (expect_type));
}
/* Found a function symbol. Now we will substitute its
value in place of the message dispatcher (obj_msgSend),
so that we call the method directly instead of thru
the dispatcher. The main reason for doing this is that
we can now evaluate the return value and parameter values
according to their known data types, in case we need to
do things like promotion, dereferencing, special handling
of structs and doubles, etc.
We want to use the type signature of 'method', but still
jump to objc_msgSend() or objc_msgSend_stret() to better
mimic the behavior of the runtime. */
if (method)
{
if (method->type ()->code () != TYPE_CODE_FUNC)
error (_("method address has symbol information "
"with non-function type; skipping"));
/* Create a function pointer of the appropriate type, and
replace its value with the value of msg_send or
msg_send_stret. We must use a pointer here, as
msg_send and msg_send_stret are of pointer type, and
the representation may be different on systems that use
function descriptors. */
if (struct_return)
called_method
= value_from_pointer (lookup_pointer_type (method->type ()),
value_as_address (msg_send_stret));
else
called_method
= value_from_pointer (lookup_pointer_type (method->type ()),
value_as_address (msg_send));
}
else
{
if (struct_return)
called_method = msg_send_stret;
else
called_method = msg_send;
}
if (noside == EVAL_AVOID_SIDE_EFFECTS)
{
/* If the return type doesn't look like a function type,
call an error. This can happen if somebody tries to
turn a variable into a function call. This is here
because people often want to call, eg, strcmp, which
gdb doesn't know is a function. If gdb isn't asked for
it's opinion (ie. through "whatis"), it won't offer
it. */
struct type *callee_type = called_method->type ();
if (callee_type && callee_type->code () == TYPE_CODE_PTR)
callee_type = callee_type->target_type ();
callee_type = callee_type->target_type ();
if (callee_type)
{
if ((callee_type->code () == TYPE_CODE_ERROR) && expect_type)
return value::allocate (expect_type);
else
return value::allocate (callee_type);
}
else
error (_("Expression of type other than "
"\"method returning ...\" used as a method"));
}
/* Now depending on whether we found a symbol for the method,
we will either call the runtime dispatcher or the method
directly. */
args[0] = target;
args[1] = value_from_longest (long_type, selector);
if (gnu_runtime && (method != NULL))
{
/* Function objc_msg_lookup returns a pointer. */
struct type *tem_type = called_method->type ();
tem_type = lookup_pointer_type (lookup_function_type (tem_type));
called_method->deprecated_set_type (tem_type);
called_method = call_function_by_hand (called_method, NULL, args);
}
return call_function_by_hand (called_method, NULL, args);
}
/* Helper function for MULTI_SUBSCRIPT. */
static struct value *
eval_multi_subscript (struct type *expect_type, struct expression *exp,
enum noside noside, value *arg1,
gdb::array_view<value *> args)
{
for (value *arg2 : args)
{
if (binop_user_defined_p (MULTI_SUBSCRIPT, arg1, arg2))
{
arg1 = value_x_binop (arg1, arg2, MULTI_SUBSCRIPT, OP_NULL, noside);
}
else
{
arg1 = coerce_ref (arg1);
struct type *type = check_typedef (arg1->type ());
switch (type->code ())
{
case TYPE_CODE_PTR:
case TYPE_CODE_ARRAY:
case TYPE_CODE_STRING:
arg1 = value_subscript (arg1, value_as_long (arg2));
break;
default:
if (type->name ())
error (_("cannot subscript something of type `%s'"),
type->name ());
else
error (_("cannot subscript requested type"));
}
}
}
return (arg1);
}
namespace expr
{
value *
objc_msgcall_operation::evaluate (struct type *expect_type,
struct expression *exp,
enum noside noside)
{
enum noside sub_no_side = EVAL_NORMAL;
struct type *selector_type = builtin_type (exp->gdbarch)->builtin_data_ptr;
if (noside == EVAL_AVOID_SIDE_EFFECTS)
sub_no_side = EVAL_NORMAL;
else
sub_no_side = noside;
value *target
= std::get<1> (m_storage)->evaluate (selector_type, exp, sub_no_side);
if (value_as_long (target) == 0)
sub_no_side = EVAL_AVOID_SIDE_EFFECTS;
else
sub_no_side = noside;
std::vector<operation_up> &args = std::get<2> (m_storage);
value **argvec = XALLOCAVEC (struct value *, args.size () + 3);
argvec[0] = nullptr;
argvec[1] = nullptr;
for (int i = 0; i < args.size (); ++i)
argvec[i + 2] = args[i]->evaluate_with_coercion (exp, sub_no_side);
argvec[args.size () + 2] = nullptr;
return eval_op_objc_msgcall (expect_type, exp, noside, std::
get<0> (m_storage), target,
gdb::make_array_view (argvec,
args.size () + 3));
}
value *
multi_subscript_operation::evaluate (struct type *expect_type,
struct expression *exp,
enum noside noside)
{
value *arg1 = std::get<0> (m_storage)->evaluate_with_coercion (exp, noside);
std::vector<operation_up> &values = std::get<1> (m_storage);
value **argvec = XALLOCAVEC (struct value *, values.size ());
for (int ix = 0; ix < values.size (); ++ix)
argvec[ix] = values[ix]->evaluate_with_coercion (exp, noside);
return eval_multi_subscript (expect_type, exp, noside, arg1,
gdb::make_array_view (argvec, values.size ()));
}
value *
logical_and_operation::evaluate (struct type *expect_type,
struct expression *exp,
enum noside noside)
{
value *arg1 = std::get<0> (m_storage)->evaluate (nullptr, exp, noside);
value *arg2 = std::get<1> (m_storage)->evaluate (nullptr, exp,
EVAL_AVOID_SIDE_EFFECTS);
if (binop_user_defined_p (BINOP_LOGICAL_AND, arg1, arg2))
{
arg2 = std::get<1> (m_storage)->evaluate (nullptr, exp, noside);
return value_x_binop (arg1, arg2, BINOP_LOGICAL_AND, OP_NULL, noside);
}
else
{
bool tem = value_logical_not (arg1);
if (!tem)
{
arg2 = std::get<1> (m_storage)->evaluate (nullptr, exp, noside);
tem = value_logical_not (arg2);
}
struct type *type = language_bool_type (exp->language_defn,
exp->gdbarch);
return value_from_longest (type, !tem);
}
}
value *
logical_or_operation::evaluate (struct type *expect_type,
struct expression *exp,
enum noside noside)
{
value *arg1 = std::get<0> (m_storage)->evaluate (nullptr, exp, noside);
value *arg2 = std::get<1> (m_storage)->evaluate (nullptr, exp,
EVAL_AVOID_SIDE_EFFECTS);
if (binop_user_defined_p (BINOP_LOGICAL_OR, arg1, arg2))
{
arg2 = std::get<1> (m_storage)->evaluate (nullptr, exp, noside);
return value_x_binop (arg1, arg2, BINOP_LOGICAL_OR, OP_NULL, noside);
}
else
{
bool tem = value_logical_not (arg1);
if (tem)
{
arg2 = std::get<1> (m_storage)->evaluate (nullptr, exp, noside);
tem = value_logical_not (arg2);
}
struct type *type = language_bool_type (exp->language_defn,
exp->gdbarch);
return value_from_longest (type, !tem);
}
}
value *
adl_func_operation::evaluate (struct type *expect_type,
struct expression *exp,
enum noside noside)
{
std::vector<operation_up> &arg_ops = std::get<2> (m_storage);
std::vector<value *> args (arg_ops.size ());
for (int i = 0; i < arg_ops.size (); ++i)
args[i] = arg_ops[i]->evaluate_with_coercion (exp, noside);
struct symbol *symp;
find_overload_match (args, std::get<0> (m_storage).c_str (),
NON_METHOD,
nullptr, nullptr,
nullptr, &symp, nullptr, 0, noside);
if (symp->type ()->code () == TYPE_CODE_ERROR)
error_unknown_type (symp->print_name ());
value *callee = evaluate_var_value (noside, std::get<1> (m_storage), symp);
return evaluate_subexp_do_call (exp, noside, callee, args,
nullptr, expect_type);
}
/* This function evaluates brace-initializers (in C/C++) for
structure types. */
struct value *
array_operation::evaluate_struct_tuple (struct value *struct_val,
struct expression *exp,
enum noside noside, int nargs)
{
const std::vector<operation_up> &in_args = std::get<2> (m_storage);
struct type *struct_type = check_typedef (struct_val->type ());
struct type *field_type;
int fieldno = -1;
int idx = 0;
while (--nargs >= 0)
{
struct value *val = NULL;
int bitpos, bitsize;
bfd_byte *addr;
fieldno++;
/* Skip static fields. */
while (fieldno < struct_type->num_fields ()
&& struct_type->field (fieldno).is_static ())
fieldno++;
if (fieldno >= struct_type->num_fields ())
error (_("too many initializers"));
field_type = struct_type->field (fieldno).type ();
if (field_type->code () == TYPE_CODE_UNION
&& struct_type->field (fieldno).name ()[0] == '0')
error (_("don't know which variant you want to set"));
/* Here, struct_type is the type of the inner struct,
while substruct_type is the type of the inner struct.
These are the same for normal structures, but a variant struct
contains anonymous union fields that contain substruct fields.
The value fieldno is the index of the top-level (normal or
anonymous union) field in struct_field, while the value
subfieldno is the index of the actual real (named inner) field
in substruct_type. */
field_type = struct_type->field (fieldno).type ();
if (val == 0)
val = in_args[idx++]->evaluate (field_type, exp, noside);
/* Now actually set the field in struct_val. */
/* Assign val to field fieldno. */
if (val->type () != field_type)
val = value_cast (field_type, val);
bitsize = struct_type->field (fieldno).bitsize ();
bitpos = struct_type->field (fieldno).loc_bitpos ();
addr = struct_val->contents_writeable ().data () + bitpos / 8;
if (bitsize)
modify_field (struct_type, addr,
value_as_long (val), bitpos % 8, bitsize);
else
memcpy (addr, val->contents ().data (),
val->type ()->length ());
}
return struct_val;
}
value *
array_operation::evaluate (struct type *expect_type,
struct expression *exp,
enum noside noside)
{
const int provided_low_bound = std::get<0> (m_storage);
const std::vector<operation_up> &in_args = std::get<2> (m_storage);
const int nargs = std::get<1> (m_storage) - provided_low_bound + 1;
struct type *type = expect_type ? check_typedef (expect_type) : nullptr;
Remove EVAL_SKIP EVAL_SKIP was needed in the old expression implementation due to its linearized tree structure. This is not needed in the new implementation, because it is trivial to not evaluate a subexpression. This patch removes the last vestiges of EVAL_SKIP. gdb/ChangeLog 2021-03-08 Tom Tromey <tom@tromey.com> * value.h (eval_skip_value): Don't declare. * opencl-lang.c (eval_opencl_assign): Update. * m2-lang.c (eval_op_m2_high, eval_op_m2_subscript): Update. * f-lang.c (eval_op_f_abs, eval_op_f_mod, eval_op_f_ceil) (eval_op_f_floor, eval_op_f_modulo, eval_op_f_cmplx): Remove. * expression.h (enum noside) <EVAL_SKIP>: Remove. * expop.h (typeof_operation::evaluate) (decltype_operation::evaluate, unop_addr_operation::evaluate) (unop_sizeof_operation::evaluate, assign_operation::evaluate) (cxx_cast_operation::evaluate): Update. * eval.c (eval_skip_value): Remove. (eval_op_scope, eval_op_var_entry_value) (eval_op_func_static_var, eval_op_string, eval_op_objc_selector) (eval_op_concat, eval_op_ternop, eval_op_structop_struct) (eval_op_structop_ptr, eval_op_member, eval_op_add, eval_op_sub) (eval_op_binary, eval_op_subscript, eval_op_equal) (eval_op_notequal, eval_op_less, eval_op_gtr, eval_op_geq) (eval_op_leq, eval_op_repeat, eval_op_plus, eval_op_neg) (eval_op_complement, eval_op_lognot, eval_op_ind) (eval_op_memval, eval_op_preinc, eval_op_predec) (eval_op_postinc, eval_op_postdec, eval_op_type) (eval_binop_assign_modify, eval_op_objc_msgcall) (eval_multi_subscript, logical_and_operation::evaluate) (logical_or_operation::evaluate, array_operation::evaluate) (operation::evaluate_for_cast) (var_msym_value_operation::evaluate_for_cast) (var_value_operation::evaluate_for_cast): Update. * c-lang.c (c_string_operation::evaluate): Update. * c-exp.h (objc_nsstring_operation::evaluate) (objc_selector_operation::evaluate): Update. * ada-lang.c (ada_assign_operation::evaluate) (eval_ternop_in_range, ada_unop_neg, ada_unop_in_range) (ada_atr_size): Update.
2021-03-08 22:27:57 +08:00
if (expect_type != nullptr
&& type->code () == TYPE_CODE_STRUCT)
{
struct value *rec = value::allocate (expect_type);
memset (rec->contents_raw ().data (), '\0', type->length ());
return evaluate_struct_tuple (rec, exp, noside, nargs);
}
Remove EVAL_SKIP EVAL_SKIP was needed in the old expression implementation due to its linearized tree structure. This is not needed in the new implementation, because it is trivial to not evaluate a subexpression. This patch removes the last vestiges of EVAL_SKIP. gdb/ChangeLog 2021-03-08 Tom Tromey <tom@tromey.com> * value.h (eval_skip_value): Don't declare. * opencl-lang.c (eval_opencl_assign): Update. * m2-lang.c (eval_op_m2_high, eval_op_m2_subscript): Update. * f-lang.c (eval_op_f_abs, eval_op_f_mod, eval_op_f_ceil) (eval_op_f_floor, eval_op_f_modulo, eval_op_f_cmplx): Remove. * expression.h (enum noside) <EVAL_SKIP>: Remove. * expop.h (typeof_operation::evaluate) (decltype_operation::evaluate, unop_addr_operation::evaluate) (unop_sizeof_operation::evaluate, assign_operation::evaluate) (cxx_cast_operation::evaluate): Update. * eval.c (eval_skip_value): Remove. (eval_op_scope, eval_op_var_entry_value) (eval_op_func_static_var, eval_op_string, eval_op_objc_selector) (eval_op_concat, eval_op_ternop, eval_op_structop_struct) (eval_op_structop_ptr, eval_op_member, eval_op_add, eval_op_sub) (eval_op_binary, eval_op_subscript, eval_op_equal) (eval_op_notequal, eval_op_less, eval_op_gtr, eval_op_geq) (eval_op_leq, eval_op_repeat, eval_op_plus, eval_op_neg) (eval_op_complement, eval_op_lognot, eval_op_ind) (eval_op_memval, eval_op_preinc, eval_op_predec) (eval_op_postinc, eval_op_postdec, eval_op_type) (eval_binop_assign_modify, eval_op_objc_msgcall) (eval_multi_subscript, logical_and_operation::evaluate) (logical_or_operation::evaluate, array_operation::evaluate) (operation::evaluate_for_cast) (var_msym_value_operation::evaluate_for_cast) (var_value_operation::evaluate_for_cast): Update. * c-lang.c (c_string_operation::evaluate): Update. * c-exp.h (objc_nsstring_operation::evaluate) (objc_selector_operation::evaluate): Update. * ada-lang.c (ada_assign_operation::evaluate) (eval_ternop_in_range, ada_unop_neg, ada_unop_in_range) (ada_atr_size): Update.
2021-03-08 22:27:57 +08:00
if (expect_type != nullptr
&& type->code () == TYPE_CODE_ARRAY)
{
struct type *range_type = type->index_type ();
struct type *element_type = type->target_type ();
struct value *array = value::allocate (expect_type);
int element_size = check_typedef (element_type)->length ();
LONGEST low_bound, high_bound;
if (!get_discrete_bounds (range_type, &low_bound, &high_bound))
{
low_bound = 0;
high_bound = (type->length () / element_size) - 1;
}
if (low_bound + nargs - 1 > high_bound)
error (_("Too many array elements"));
memset (array->contents_raw ().data (), 0, expect_type->length ());
for (int idx = 0; idx < nargs; ++idx)
{
struct value *element;
element = in_args[idx]->evaluate (element_type, exp, noside);
if (element->type () != element_type)
element = value_cast (element_type, element);
memcpy (array->contents_raw ().data () + idx * element_size,
element->contents ().data (),
element_size);
}
return array;
}
Remove EVAL_SKIP EVAL_SKIP was needed in the old expression implementation due to its linearized tree structure. This is not needed in the new implementation, because it is trivial to not evaluate a subexpression. This patch removes the last vestiges of EVAL_SKIP. gdb/ChangeLog 2021-03-08 Tom Tromey <tom@tromey.com> * value.h (eval_skip_value): Don't declare. * opencl-lang.c (eval_opencl_assign): Update. * m2-lang.c (eval_op_m2_high, eval_op_m2_subscript): Update. * f-lang.c (eval_op_f_abs, eval_op_f_mod, eval_op_f_ceil) (eval_op_f_floor, eval_op_f_modulo, eval_op_f_cmplx): Remove. * expression.h (enum noside) <EVAL_SKIP>: Remove. * expop.h (typeof_operation::evaluate) (decltype_operation::evaluate, unop_addr_operation::evaluate) (unop_sizeof_operation::evaluate, assign_operation::evaluate) (cxx_cast_operation::evaluate): Update. * eval.c (eval_skip_value): Remove. (eval_op_scope, eval_op_var_entry_value) (eval_op_func_static_var, eval_op_string, eval_op_objc_selector) (eval_op_concat, eval_op_ternop, eval_op_structop_struct) (eval_op_structop_ptr, eval_op_member, eval_op_add, eval_op_sub) (eval_op_binary, eval_op_subscript, eval_op_equal) (eval_op_notequal, eval_op_less, eval_op_gtr, eval_op_geq) (eval_op_leq, eval_op_repeat, eval_op_plus, eval_op_neg) (eval_op_complement, eval_op_lognot, eval_op_ind) (eval_op_memval, eval_op_preinc, eval_op_predec) (eval_op_postinc, eval_op_postdec, eval_op_type) (eval_binop_assign_modify, eval_op_objc_msgcall) (eval_multi_subscript, logical_and_operation::evaluate) (logical_or_operation::evaluate, array_operation::evaluate) (operation::evaluate_for_cast) (var_msym_value_operation::evaluate_for_cast) (var_value_operation::evaluate_for_cast): Update. * c-lang.c (c_string_operation::evaluate): Update. * c-exp.h (objc_nsstring_operation::evaluate) (objc_selector_operation::evaluate): Update. * ada-lang.c (ada_assign_operation::evaluate) (eval_ternop_in_range, ada_unop_neg, ada_unop_in_range) (ada_atr_size): Update.
2021-03-08 22:27:57 +08:00
if (expect_type != nullptr
&& type->code () == TYPE_CODE_SET)
{
struct value *set = value::allocate (expect_type);
gdb_byte *valaddr = set->contents_raw ().data ();
struct type *element_type = type->index_type ();
struct type *check_type = element_type;
LONGEST low_bound, high_bound;
/* Get targettype of elementtype. */
while (check_type->code () == TYPE_CODE_RANGE
|| check_type->code () == TYPE_CODE_TYPEDEF)
check_type = check_type->target_type ();
if (!get_discrete_bounds (element_type, &low_bound, &high_bound))
error (_("(power)set type with unknown size"));
memset (valaddr, '\0', type->length ());
for (int idx = 0; idx < nargs; idx++)
{
LONGEST range_low, range_high;
struct type *range_low_type, *range_high_type;
struct value *elem_val;
elem_val = in_args[idx]->evaluate (element_type, exp, noside);
range_low_type = range_high_type = elem_val->type ();
range_low = range_high = value_as_long (elem_val);
/* Check types of elements to avoid mixture of elements from
different types. Also check if type of element is "compatible"
with element type of powerset. */
if (range_low_type->code () == TYPE_CODE_RANGE)
range_low_type = range_low_type->target_type ();
if (range_high_type->code () == TYPE_CODE_RANGE)
range_high_type = range_high_type->target_type ();
if ((range_low_type->code () != range_high_type->code ())
|| (range_low_type->code () == TYPE_CODE_ENUM
&& (range_low_type != range_high_type)))
/* different element modes. */
error (_("POWERSET tuple elements of different mode"));
if ((check_type->code () != range_low_type->code ())
|| (check_type->code () == TYPE_CODE_ENUM
&& range_low_type != check_type))
error (_("incompatible POWERSET tuple elements"));
if (range_low > range_high)
{
warning (_("empty POWERSET tuple range"));
continue;
}
if (range_low < low_bound || range_high > high_bound)
error (_("POWERSET tuple element out of range"));
range_low -= low_bound;
range_high -= low_bound;
for (; range_low <= range_high; range_low++)
{
int bit_index = (unsigned) range_low % TARGET_CHAR_BIT;
if (gdbarch_byte_order (exp->gdbarch) == BFD_ENDIAN_BIG)
bit_index = TARGET_CHAR_BIT - 1 - bit_index;
valaddr[(unsigned) range_low / TARGET_CHAR_BIT]
|= 1 << bit_index;
}
}
return set;
}
std::vector<value *> argvec (nargs);
for (int tem = 0; tem < nargs; tem++)
{
/* Ensure that array expressions are coerced into pointer
objects. */
argvec[tem] = in_args[tem]->evaluate_with_coercion (exp, noside);
}
return value_array (provided_low_bound, argvec);
}
gdb/x86: handle stap probe arguments in xmm registers On x86 machines with xmm register, and with recent versions of systemtap (and gcc?), it can occur that stap probe arguments will be placed into xmm registers. I notice this happening on a current Fedora Rawhide install with the following package versions installed: $ rpm -q glibc systemtap gcc glibc-2.35.9000-10.fc37.x86_64 systemtap-4.7~pre16468670g9f253544-1.fc37.x86_64 gcc-12.0.1-0.12.fc37.x86_64 If I check the probe data in libc, I see this: $ readelf -n /lib64/libc.so.6 ... stapsdt 0x0000004d NT_STAPSDT (SystemTap probe descriptors) Provider: libc Name: pthread_start Location: 0x0000000000090ac3, Base: 0x00000000001c65c4, Semaphore: 0x0000000000000000 Arguments: 8@%xmm1 8@1600(%rbx) 8@1608(%rbx) stapsdt 0x00000050 NT_STAPSDT (SystemTap probe descriptors) Provider: libc Name: pthread_create Location: 0x00000000000912f1, Base: 0x00000000001c65c4, Semaphore: 0x0000000000000000 Arguments: 8@%xmm1 8@%r13 8@8(%rsp) 8@16(%rsp) ... Notice that for both of these probes, the first argument is a uint64_t stored in the xmm1 register. Unfortunately, if I try to use this probe within GDB, then I can't view the first argument. Here's an example session: $ gdb $(which gdb) (gdb) start ... (gdb) info probes stap libc pthread_create ... (gdb) break *0x00007ffff729e2f1 # Use address of probe. (gdb) continue ... (gdb) p $_probe_arg0 Invalid cast. What's going wrong? If I re-run my session, but this time use 'set debug stap-expression 1', this is what I see: (gdb) set debug stap-expression 1 (gdb) p $_probe_arg0 Operation: UNOP_CAST Operation: OP_REGISTER String: xmm1 Type: uint64_t Operation: UNOP_CAST Operation: OP_REGISTER String: r13 Type: uint64_t Operation: UNOP_CAST Operation: UNOP_IND Operation: UNOP_CAST Operation: BINOP_ADD Operation: OP_LONG Type: long Constant: 0x0000000000000008 Operation: OP_REGISTER String: rsp Type: uint64_t * Type: uint64_t Operation: UNOP_CAST Operation: UNOP_IND Operation: UNOP_CAST Operation: BINOP_ADD Operation: OP_LONG Type: long Constant: 0x0000000000000010 Operation: OP_REGISTER String: rsp Type: uint64_t * Type: uint64_t Invalid cast. (gdb) The important bit is this: Operation: UNOP_CAST Operation: OP_REGISTER String: xmm1 Type: uint64_t Which is where we cast the xmm1 register to uint64_t. And the final piece of the puzzle is: (gdb) ptype $xmm1 type = union vec128 { v8bf16 v8_bfloat16; v4f v4_float; v2d v2_double; v16i8 v16_int8; v8i16 v8_int16; v4i32 v4_int32; v2i64 v2_int64; uint128_t uint128; } So, we are attempting to cast a union type to a scalar type, which is not supporting in C/C++, and as a consequence GDB's expression evaluator throws an error when we attempt to do this. The first approach I considered for solving this problem was to try and make use of gdbarch_stap_adjust_register. We already have a gdbarch method (gdbarch_stap_adjust_register) that allows us to tweak the name of the register that we access. Currently only x86 architectures use this to transform things like ax to eax in some cases. I wondered, what if we change gdbarch_stap_adjust_register to do more than just change the register names? What if this method instead became gdbarch_stap_read_register. This new method would return a operation_up, and would take the register name, and the type we are trying to read from the register, and return the operation that actually reads the register. The default implementation of this method would just use user_reg_map_name_to_regnum, and then create a register_operation, like we already do in stap_parse_register_operand. But, for x86 architectures this method would fist possibly adjust the register name, then do the default action to read the register. Finally, for x86 this method would spot when we were accessing an xmm register, and, based on the type being pulled from the register, would extract the correct field from the union. The benefit of this approach is that it would work with the expression types that GDB currently supports. The draw back would be that this approach would not be very generic. We'd need code to handle each sub-field size with an xmm register. If other architectures started using vector registers for probe arguments, those architectures would have to create their own gdbarch_stap_read_register method. And finally, the type of the xmm registers comes from the type defined in the target description, there's a risk that GDB might end up hard-coding the names of type sub-fields, then if a target uses a different target description, with different field names for xmm registers, the stap probes would stop working. And so, based on all the above draw backs, I rejected this first approach. My second plan involves adding a new expression type to GDB called unop_extract_operation. This new expression takes a value and a type, during evaluation the value contents are fetched, and then a new value is extracted from the value contents (based on type). This is similar to the following C expression: result_value = *((output_type *) &input_value); Obviously we can't actually build this expression in this case, as the input_value is in a register, but hopefully the above makes it clearer what I'm trying to do. The benefit of the new expression approach is that this code can be shared across all architectures, and it doesn't care about sub-field names within the union type. The draw-backs that I see are potential future problems if arguments are not stored within the least significant bytes of the register. However if/when that becomes an issue we can adapt the gdbarch_stap_read_register approach to allow architectures to control how a value is extracted. For testing, I've extended the existing gdb.base/stap-probe.exp test to include a function that tries to force an argument into an xmm register. Obviously, that will only work on a x86 target, so I've guarded the new function with an appropriate GCC define. In the exp script we use readelf to check if the probe exists, and is using the xmm register. If the probe doesn't exist then the associated tests are skipped. If the probe exists, put isn't using the xmm register (which will depend on systemtap/gcc versions), then again, the tests are skipped. Otherwise, we can run the test. I think the cost of running readelf is pretty low, so I don't feel too bad making all the non-xmm targets running this step. I found that on a Fedora 35 install, with these packages installed, I was able to run this test and have the probe argument be placed in an xmm register: $ rpm -q systemtap gcc glibc systemtap-4.6-4.fc35.x86_64 gcc-11.2.1-9.fc35.x86_64 glibc-2.34-7.fc35.x86_64 Finally, as this patch adds a new operation type, then I need to consider how to generate an agent expression for the new operation type. I have kicked the can down the road a bit on this. In the function stap_parse_register_operand, I only create a unop_extract_operation in the case where the register type is non-scalar, this means that in most cases I don't need to worry about generating an agent expression at all. In the xmm register case, when an unop_extract_operation will be created, I have sketched out how the agent expression could be handled, however, this code is currently not reached. When we try to generate the agent expression to place the xmm register on the stack, GDB hits this error: (gdb) trace -probe-stap test:xmmreg Tracepoint 1 at 0x401166 (gdb) actions Enter actions for tracepoint 1, one per line. End with a line saying just "end". >collect $_probe_arg0 Value not scalar: cannot be an rvalue. This is because GDB doesn't currently support placing non-scalar types on the agent expression evaluation stack. Solving this is clearly related to the original problem, but feels a bit like a second problem. I'd like to get feedback on whether my approach to solving the original problem is acceptable or not before I start looking at how to handle xmm registers within agent expressions.
2022-03-11 00:57:18 +08:00
value *
unop_extract_operation::evaluate (struct type *expect_type,
struct expression *exp,
enum noside noside)
{
value *old_value = std::get<0> (m_storage)->evaluate (nullptr, exp, noside);
struct type *type = get_type ();
if (type->length () > old_value->type ()->length ())
gdb/x86: handle stap probe arguments in xmm registers On x86 machines with xmm register, and with recent versions of systemtap (and gcc?), it can occur that stap probe arguments will be placed into xmm registers. I notice this happening on a current Fedora Rawhide install with the following package versions installed: $ rpm -q glibc systemtap gcc glibc-2.35.9000-10.fc37.x86_64 systemtap-4.7~pre16468670g9f253544-1.fc37.x86_64 gcc-12.0.1-0.12.fc37.x86_64 If I check the probe data in libc, I see this: $ readelf -n /lib64/libc.so.6 ... stapsdt 0x0000004d NT_STAPSDT (SystemTap probe descriptors) Provider: libc Name: pthread_start Location: 0x0000000000090ac3, Base: 0x00000000001c65c4, Semaphore: 0x0000000000000000 Arguments: 8@%xmm1 8@1600(%rbx) 8@1608(%rbx) stapsdt 0x00000050 NT_STAPSDT (SystemTap probe descriptors) Provider: libc Name: pthread_create Location: 0x00000000000912f1, Base: 0x00000000001c65c4, Semaphore: 0x0000000000000000 Arguments: 8@%xmm1 8@%r13 8@8(%rsp) 8@16(%rsp) ... Notice that for both of these probes, the first argument is a uint64_t stored in the xmm1 register. Unfortunately, if I try to use this probe within GDB, then I can't view the first argument. Here's an example session: $ gdb $(which gdb) (gdb) start ... (gdb) info probes stap libc pthread_create ... (gdb) break *0x00007ffff729e2f1 # Use address of probe. (gdb) continue ... (gdb) p $_probe_arg0 Invalid cast. What's going wrong? If I re-run my session, but this time use 'set debug stap-expression 1', this is what I see: (gdb) set debug stap-expression 1 (gdb) p $_probe_arg0 Operation: UNOP_CAST Operation: OP_REGISTER String: xmm1 Type: uint64_t Operation: UNOP_CAST Operation: OP_REGISTER String: r13 Type: uint64_t Operation: UNOP_CAST Operation: UNOP_IND Operation: UNOP_CAST Operation: BINOP_ADD Operation: OP_LONG Type: long Constant: 0x0000000000000008 Operation: OP_REGISTER String: rsp Type: uint64_t * Type: uint64_t Operation: UNOP_CAST Operation: UNOP_IND Operation: UNOP_CAST Operation: BINOP_ADD Operation: OP_LONG Type: long Constant: 0x0000000000000010 Operation: OP_REGISTER String: rsp Type: uint64_t * Type: uint64_t Invalid cast. (gdb) The important bit is this: Operation: UNOP_CAST Operation: OP_REGISTER String: xmm1 Type: uint64_t Which is where we cast the xmm1 register to uint64_t. And the final piece of the puzzle is: (gdb) ptype $xmm1 type = union vec128 { v8bf16 v8_bfloat16; v4f v4_float; v2d v2_double; v16i8 v16_int8; v8i16 v8_int16; v4i32 v4_int32; v2i64 v2_int64; uint128_t uint128; } So, we are attempting to cast a union type to a scalar type, which is not supporting in C/C++, and as a consequence GDB's expression evaluator throws an error when we attempt to do this. The first approach I considered for solving this problem was to try and make use of gdbarch_stap_adjust_register. We already have a gdbarch method (gdbarch_stap_adjust_register) that allows us to tweak the name of the register that we access. Currently only x86 architectures use this to transform things like ax to eax in some cases. I wondered, what if we change gdbarch_stap_adjust_register to do more than just change the register names? What if this method instead became gdbarch_stap_read_register. This new method would return a operation_up, and would take the register name, and the type we are trying to read from the register, and return the operation that actually reads the register. The default implementation of this method would just use user_reg_map_name_to_regnum, and then create a register_operation, like we already do in stap_parse_register_operand. But, for x86 architectures this method would fist possibly adjust the register name, then do the default action to read the register. Finally, for x86 this method would spot when we were accessing an xmm register, and, based on the type being pulled from the register, would extract the correct field from the union. The benefit of this approach is that it would work with the expression types that GDB currently supports. The draw back would be that this approach would not be very generic. We'd need code to handle each sub-field size with an xmm register. If other architectures started using vector registers for probe arguments, those architectures would have to create their own gdbarch_stap_read_register method. And finally, the type of the xmm registers comes from the type defined in the target description, there's a risk that GDB might end up hard-coding the names of type sub-fields, then if a target uses a different target description, with different field names for xmm registers, the stap probes would stop working. And so, based on all the above draw backs, I rejected this first approach. My second plan involves adding a new expression type to GDB called unop_extract_operation. This new expression takes a value and a type, during evaluation the value contents are fetched, and then a new value is extracted from the value contents (based on type). This is similar to the following C expression: result_value = *((output_type *) &input_value); Obviously we can't actually build this expression in this case, as the input_value is in a register, but hopefully the above makes it clearer what I'm trying to do. The benefit of the new expression approach is that this code can be shared across all architectures, and it doesn't care about sub-field names within the union type. The draw-backs that I see are potential future problems if arguments are not stored within the least significant bytes of the register. However if/when that becomes an issue we can adapt the gdbarch_stap_read_register approach to allow architectures to control how a value is extracted. For testing, I've extended the existing gdb.base/stap-probe.exp test to include a function that tries to force an argument into an xmm register. Obviously, that will only work on a x86 target, so I've guarded the new function with an appropriate GCC define. In the exp script we use readelf to check if the probe exists, and is using the xmm register. If the probe doesn't exist then the associated tests are skipped. If the probe exists, put isn't using the xmm register (which will depend on systemtap/gcc versions), then again, the tests are skipped. Otherwise, we can run the test. I think the cost of running readelf is pretty low, so I don't feel too bad making all the non-xmm targets running this step. I found that on a Fedora 35 install, with these packages installed, I was able to run this test and have the probe argument be placed in an xmm register: $ rpm -q systemtap gcc glibc systemtap-4.6-4.fc35.x86_64 gcc-11.2.1-9.fc35.x86_64 glibc-2.34-7.fc35.x86_64 Finally, as this patch adds a new operation type, then I need to consider how to generate an agent expression for the new operation type. I have kicked the can down the road a bit on this. In the function stap_parse_register_operand, I only create a unop_extract_operation in the case where the register type is non-scalar, this means that in most cases I don't need to worry about generating an agent expression at all. In the xmm register case, when an unop_extract_operation will be created, I have sketched out how the agent expression could be handled, however, this code is currently not reached. When we try to generate the agent expression to place the xmm register on the stack, GDB hits this error: (gdb) trace -probe-stap test:xmmreg Tracepoint 1 at 0x401166 (gdb) actions Enter actions for tracepoint 1, one per line. End with a line saying just "end". >collect $_probe_arg0 Value not scalar: cannot be an rvalue. This is because GDB doesn't currently support placing non-scalar types on the agent expression evaluation stack. Solving this is clearly related to the original problem, but feels a bit like a second problem. I'd like to get feedback on whether my approach to solving the original problem is acceptable or not before I start looking at how to handle xmm registers within agent expressions.
2022-03-11 00:57:18 +08:00
error (_("length type is larger than the value type"));
struct value *result = value::allocate (type);
old_value->contents_copy (result, 0, 0, type->length ());
gdb/x86: handle stap probe arguments in xmm registers On x86 machines with xmm register, and with recent versions of systemtap (and gcc?), it can occur that stap probe arguments will be placed into xmm registers. I notice this happening on a current Fedora Rawhide install with the following package versions installed: $ rpm -q glibc systemtap gcc glibc-2.35.9000-10.fc37.x86_64 systemtap-4.7~pre16468670g9f253544-1.fc37.x86_64 gcc-12.0.1-0.12.fc37.x86_64 If I check the probe data in libc, I see this: $ readelf -n /lib64/libc.so.6 ... stapsdt 0x0000004d NT_STAPSDT (SystemTap probe descriptors) Provider: libc Name: pthread_start Location: 0x0000000000090ac3, Base: 0x00000000001c65c4, Semaphore: 0x0000000000000000 Arguments: 8@%xmm1 8@1600(%rbx) 8@1608(%rbx) stapsdt 0x00000050 NT_STAPSDT (SystemTap probe descriptors) Provider: libc Name: pthread_create Location: 0x00000000000912f1, Base: 0x00000000001c65c4, Semaphore: 0x0000000000000000 Arguments: 8@%xmm1 8@%r13 8@8(%rsp) 8@16(%rsp) ... Notice that for both of these probes, the first argument is a uint64_t stored in the xmm1 register. Unfortunately, if I try to use this probe within GDB, then I can't view the first argument. Here's an example session: $ gdb $(which gdb) (gdb) start ... (gdb) info probes stap libc pthread_create ... (gdb) break *0x00007ffff729e2f1 # Use address of probe. (gdb) continue ... (gdb) p $_probe_arg0 Invalid cast. What's going wrong? If I re-run my session, but this time use 'set debug stap-expression 1', this is what I see: (gdb) set debug stap-expression 1 (gdb) p $_probe_arg0 Operation: UNOP_CAST Operation: OP_REGISTER String: xmm1 Type: uint64_t Operation: UNOP_CAST Operation: OP_REGISTER String: r13 Type: uint64_t Operation: UNOP_CAST Operation: UNOP_IND Operation: UNOP_CAST Operation: BINOP_ADD Operation: OP_LONG Type: long Constant: 0x0000000000000008 Operation: OP_REGISTER String: rsp Type: uint64_t * Type: uint64_t Operation: UNOP_CAST Operation: UNOP_IND Operation: UNOP_CAST Operation: BINOP_ADD Operation: OP_LONG Type: long Constant: 0x0000000000000010 Operation: OP_REGISTER String: rsp Type: uint64_t * Type: uint64_t Invalid cast. (gdb) The important bit is this: Operation: UNOP_CAST Operation: OP_REGISTER String: xmm1 Type: uint64_t Which is where we cast the xmm1 register to uint64_t. And the final piece of the puzzle is: (gdb) ptype $xmm1 type = union vec128 { v8bf16 v8_bfloat16; v4f v4_float; v2d v2_double; v16i8 v16_int8; v8i16 v8_int16; v4i32 v4_int32; v2i64 v2_int64; uint128_t uint128; } So, we are attempting to cast a union type to a scalar type, which is not supporting in C/C++, and as a consequence GDB's expression evaluator throws an error when we attempt to do this. The first approach I considered for solving this problem was to try and make use of gdbarch_stap_adjust_register. We already have a gdbarch method (gdbarch_stap_adjust_register) that allows us to tweak the name of the register that we access. Currently only x86 architectures use this to transform things like ax to eax in some cases. I wondered, what if we change gdbarch_stap_adjust_register to do more than just change the register names? What if this method instead became gdbarch_stap_read_register. This new method would return a operation_up, and would take the register name, and the type we are trying to read from the register, and return the operation that actually reads the register. The default implementation of this method would just use user_reg_map_name_to_regnum, and then create a register_operation, like we already do in stap_parse_register_operand. But, for x86 architectures this method would fist possibly adjust the register name, then do the default action to read the register. Finally, for x86 this method would spot when we were accessing an xmm register, and, based on the type being pulled from the register, would extract the correct field from the union. The benefit of this approach is that it would work with the expression types that GDB currently supports. The draw back would be that this approach would not be very generic. We'd need code to handle each sub-field size with an xmm register. If other architectures started using vector registers for probe arguments, those architectures would have to create their own gdbarch_stap_read_register method. And finally, the type of the xmm registers comes from the type defined in the target description, there's a risk that GDB might end up hard-coding the names of type sub-fields, then if a target uses a different target description, with different field names for xmm registers, the stap probes would stop working. And so, based on all the above draw backs, I rejected this first approach. My second plan involves adding a new expression type to GDB called unop_extract_operation. This new expression takes a value and a type, during evaluation the value contents are fetched, and then a new value is extracted from the value contents (based on type). This is similar to the following C expression: result_value = *((output_type *) &input_value); Obviously we can't actually build this expression in this case, as the input_value is in a register, but hopefully the above makes it clearer what I'm trying to do. The benefit of the new expression approach is that this code can be shared across all architectures, and it doesn't care about sub-field names within the union type. The draw-backs that I see are potential future problems if arguments are not stored within the least significant bytes of the register. However if/when that becomes an issue we can adapt the gdbarch_stap_read_register approach to allow architectures to control how a value is extracted. For testing, I've extended the existing gdb.base/stap-probe.exp test to include a function that tries to force an argument into an xmm register. Obviously, that will only work on a x86 target, so I've guarded the new function with an appropriate GCC define. In the exp script we use readelf to check if the probe exists, and is using the xmm register. If the probe doesn't exist then the associated tests are skipped. If the probe exists, put isn't using the xmm register (which will depend on systemtap/gcc versions), then again, the tests are skipped. Otherwise, we can run the test. I think the cost of running readelf is pretty low, so I don't feel too bad making all the non-xmm targets running this step. I found that on a Fedora 35 install, with these packages installed, I was able to run this test and have the probe argument be placed in an xmm register: $ rpm -q systemtap gcc glibc systemtap-4.6-4.fc35.x86_64 gcc-11.2.1-9.fc35.x86_64 glibc-2.34-7.fc35.x86_64 Finally, as this patch adds a new operation type, then I need to consider how to generate an agent expression for the new operation type. I have kicked the can down the road a bit on this. In the function stap_parse_register_operand, I only create a unop_extract_operation in the case where the register type is non-scalar, this means that in most cases I don't need to worry about generating an agent expression at all. In the xmm register case, when an unop_extract_operation will be created, I have sketched out how the agent expression could be handled, however, this code is currently not reached. When we try to generate the agent expression to place the xmm register on the stack, GDB hits this error: (gdb) trace -probe-stap test:xmmreg Tracepoint 1 at 0x401166 (gdb) actions Enter actions for tracepoint 1, one per line. End with a line saying just "end". >collect $_probe_arg0 Value not scalar: cannot be an rvalue. This is because GDB doesn't currently support placing non-scalar types on the agent expression evaluation stack. Solving this is clearly related to the original problem, but feels a bit like a second problem. I'd like to get feedback on whether my approach to solving the original problem is acceptable or not before I start looking at how to handle xmm registers within agent expressions.
2022-03-11 00:57:18 +08:00
return result;
}
}
/* Helper for evaluate_subexp_for_address. */
static value *
evaluate_subexp_for_address_base (struct expression *exp, enum noside noside,
value *x)
{
if (noside == EVAL_AVOID_SIDE_EFFECTS)
{
struct type *type = check_typedef (x->type ());
if (TYPE_IS_REFERENCE (type))
return value::zero (lookup_pointer_type (type->target_type ()),
not_lval);
else if (x->lval () == lval_memory || value_must_coerce_to_target (x))
return value::zero (lookup_pointer_type (x->type ()),
not_lval);
else
error (_("Attempt to take address of "
"value not located in memory."));
}
return value_addr (x);
}
Introduce class operation This patch introduces class operation, the new base class for all expression operations. In the new approach, an operation is simply a class that presents a certain interface. Operations own their operands, and management is done via unique_ptr. The operation interface is largely ad hoc, based on the evolution of expression handling in GDB. Parts (for example, evaluate_with_coercion) are probably redundant; however I took this approach to try to avoid mixing different kinds of refactorings. In some specific situations, rather than add a generic method across the entire operation class hierarchy, I chose instead to use dynamic_cast and specialized methods on certain concrete subclasses. This will appear in some subsequent patches. One goal of this work is to avoid the kinds of easy-to-make errors that affected the old implementation. To this end, some helper subclasses are also added here. These helpers automate the implementation of the 'dump', 'uses_objfile', and 'constant_p' methods. Nearly every concrete operation that is subsequently added will use these facilities. (Note that the 'dump' implementation is only outlined here, the body appears in the next patch.) gdb/ChangeLog 2021-03-08 Tom Tromey <tom@tromey.com> * expression.h (expr::operation): New class. (expr::make_operation): New function. (expr::operation_up): New typedef. * expop.h: New file. * eval.c (operation::evaluate_for_cast) (operation::evaluate_for_address, operation::evaluate_for_sizeof): New methods. * ax-gdb.c (operation::generate_ax): New method.
2021-03-08 22:27:57 +08:00
namespace expr
{
value *
operation::evaluate_for_cast (struct type *expect_type,
struct expression *exp,
enum noside noside)
{
value *val = evaluate (expect_type, exp, noside);
return value_cast (expect_type, val);
}
value *
operation::evaluate_for_address (struct expression *exp, enum noside noside)
{
value *val = evaluate (nullptr, exp, noside);
return evaluate_subexp_for_address_base (exp, noside, val);
}
value *
scope_operation::evaluate_for_address (struct expression *exp,
enum noside noside)
{
value *x = value_aggregate_elt (std::get<0> (m_storage),
std::get<1> (m_storage).c_str (),
NULL, 1, noside);
if (x == NULL)
error (_("There is no field named %s"), std::get<1> (m_storage).c_str ());
return x;
}
value *
unop_ind_base_operation::evaluate_for_address (struct expression *exp,
enum noside noside)
{
value *x = std::get<0> (m_storage)->evaluate (nullptr, exp, noside);
/* We can't optimize out "&*" if there's a user-defined operator*. */
if (unop_user_defined_p (UNOP_IND, x))
{
x = value_x_unop (x, UNOP_IND, noside);
return evaluate_subexp_for_address_base (exp, noside, x);
}
return coerce_array (x);
}
value *
var_msym_value_operation::evaluate_for_address (struct expression *exp,
enum noside noside)
{
const bound_minimal_symbol &b = std::get<0> (m_storage);
value *val = evaluate_var_msym_value (noside, b.objfile, b.minsym);
if (noside == EVAL_AVOID_SIDE_EFFECTS)
{
struct type *type = lookup_pointer_type (val->type ());
return value::zero (type, not_lval);
}
else
return value_addr (val);
}
value *
unop_memval_operation::evaluate_for_address (struct expression *exp,
enum noside noside)
{
return value_cast (lookup_pointer_type (std::get<1> (m_storage)),
std::get<0> (m_storage)->evaluate (nullptr, exp, noside));
}
value *
unop_memval_type_operation::evaluate_for_address (struct expression *exp,
enum noside noside)
{
value *typeval = std::get<0> (m_storage)->evaluate (nullptr, exp,
EVAL_AVOID_SIDE_EFFECTS);
struct type *type = typeval->type ();
return value_cast (lookup_pointer_type (type),
std::get<1> (m_storage)->evaluate (nullptr, exp, noside));
}
value *
var_value_operation::evaluate_for_address (struct expression *exp,
enum noside noside)
{
Use block_symbol in var_value_operation I noticed that var_value_operation takes a block and a symbol, and most callers destructure a block_symbol to pass in. It seems better for this class to simply hold a block_symbol instead. Tested on x86-64 Fedora 32. gdb/ChangeLog 2021-04-15 Tom Tromey <tromey@adacore.com> * rust-exp.y (rust_parser::convert_ast_to_expression): Update. * parse.c (parser_state::push_symbol, parser_state::push_dollar): Update. * p-exp.y (variable): Update. * m2-exp.y (variable): Update. * go-exp.y (variable): Update. * expprint.c (dump_for_expression): New overload. * expop.h (check_objfile): New overload. (check_constant): New overload. (class var_value_operation): Use block_symbol. <get_symbol>: Rewrite. * eval.c (var_value_operation::evaluate) (var_value_operation::evaluate_funcall) (var_value_operation::evaluate_for_address) (var_value_operation::evaluate_for_address) (var_value_operation::evaluate_with_coercion) (var_value_operation::evaluate_for_sizeof) (var_value_operation::evaluate_for_cast): Update. * d-exp.y (PrimaryExpression): Update. * c-exp.y (variable): Update. * ax-gdb.c (var_value_operation::do_generate_ax): Update. * ada-lang.c (ada_var_value_operation::evaluate_for_cast) (ada_var_value_operation::evaluate) (ada_var_value_operation::resolve) (ada_funcall_operation::resolve): Update. * ada-exp.y (write_var_from_sym, write_object_renaming) (write_ambiguous_var, write_var_or_type, write_name_assoc) (maybe_overload): Update. * ada-exp.h (class ada_var_value_operation) <get_block>: Rewrite.
2021-04-16 00:05:00 +08:00
symbol *var = std::get<0> (m_storage).symbol;
/* C++: The "address" of a reference should yield the address
* of the object pointed to. Let value_addr() deal with it. */
if (TYPE_IS_REFERENCE (var->type ()))
return operation::evaluate_for_address (exp, noside);
if (noside == EVAL_AVOID_SIDE_EFFECTS)
{
struct type *type = lookup_pointer_type (var->type ());
enum address_class sym_class = var->aclass ();
if (sym_class == LOC_CONST
|| sym_class == LOC_CONST_BYTES
|| sym_class == LOC_REGISTER)
error (_("Attempt to take address of register or constant."));
return value::zero (type, not_lval);
}
else
Use block_symbol in var_value_operation I noticed that var_value_operation takes a block and a symbol, and most callers destructure a block_symbol to pass in. It seems better for this class to simply hold a block_symbol instead. Tested on x86-64 Fedora 32. gdb/ChangeLog 2021-04-15 Tom Tromey <tromey@adacore.com> * rust-exp.y (rust_parser::convert_ast_to_expression): Update. * parse.c (parser_state::push_symbol, parser_state::push_dollar): Update. * p-exp.y (variable): Update. * m2-exp.y (variable): Update. * go-exp.y (variable): Update. * expprint.c (dump_for_expression): New overload. * expop.h (check_objfile): New overload. (check_constant): New overload. (class var_value_operation): Use block_symbol. <get_symbol>: Rewrite. * eval.c (var_value_operation::evaluate) (var_value_operation::evaluate_funcall) (var_value_operation::evaluate_for_address) (var_value_operation::evaluate_for_address) (var_value_operation::evaluate_with_coercion) (var_value_operation::evaluate_for_sizeof) (var_value_operation::evaluate_for_cast): Update. * d-exp.y (PrimaryExpression): Update. * c-exp.y (variable): Update. * ax-gdb.c (var_value_operation::do_generate_ax): Update. * ada-lang.c (ada_var_value_operation::evaluate_for_cast) (ada_var_value_operation::evaluate) (ada_var_value_operation::resolve) (ada_funcall_operation::resolve): Update. * ada-exp.y (write_var_from_sym, write_object_renaming) (write_ambiguous_var, write_var_or_type, write_name_assoc) (maybe_overload): Update. * ada-exp.h (class ada_var_value_operation) <get_block>: Rewrite.
2021-04-16 00:05:00 +08:00
return address_of_variable (var, std::get<0> (m_storage).block);
}
value *
var_value_operation::evaluate_with_coercion (struct expression *exp,
enum noside noside)
{
Use block_symbol in var_value_operation I noticed that var_value_operation takes a block and a symbol, and most callers destructure a block_symbol to pass in. It seems better for this class to simply hold a block_symbol instead. Tested on x86-64 Fedora 32. gdb/ChangeLog 2021-04-15 Tom Tromey <tromey@adacore.com> * rust-exp.y (rust_parser::convert_ast_to_expression): Update. * parse.c (parser_state::push_symbol, parser_state::push_dollar): Update. * p-exp.y (variable): Update. * m2-exp.y (variable): Update. * go-exp.y (variable): Update. * expprint.c (dump_for_expression): New overload. * expop.h (check_objfile): New overload. (check_constant): New overload. (class var_value_operation): Use block_symbol. <get_symbol>: Rewrite. * eval.c (var_value_operation::evaluate) (var_value_operation::evaluate_funcall) (var_value_operation::evaluate_for_address) (var_value_operation::evaluate_for_address) (var_value_operation::evaluate_with_coercion) (var_value_operation::evaluate_for_sizeof) (var_value_operation::evaluate_for_cast): Update. * d-exp.y (PrimaryExpression): Update. * c-exp.y (variable): Update. * ax-gdb.c (var_value_operation::do_generate_ax): Update. * ada-lang.c (ada_var_value_operation::evaluate_for_cast) (ada_var_value_operation::evaluate) (ada_var_value_operation::resolve) (ada_funcall_operation::resolve): Update. * ada-exp.y (write_var_from_sym, write_object_renaming) (write_ambiguous_var, write_var_or_type, write_name_assoc) (maybe_overload): Update. * ada-exp.h (class ada_var_value_operation) <get_block>: Rewrite.
2021-04-16 00:05:00 +08:00
struct symbol *var = std::get<0> (m_storage).symbol;
struct type *type = check_typedef (var->type ());
if (type->code () == TYPE_CODE_ARRAY
&& !type->is_vector ()
&& CAST_IS_CONVERSION (exp->language_defn))
{
Use block_symbol in var_value_operation I noticed that var_value_operation takes a block and a symbol, and most callers destructure a block_symbol to pass in. It seems better for this class to simply hold a block_symbol instead. Tested on x86-64 Fedora 32. gdb/ChangeLog 2021-04-15 Tom Tromey <tromey@adacore.com> * rust-exp.y (rust_parser::convert_ast_to_expression): Update. * parse.c (parser_state::push_symbol, parser_state::push_dollar): Update. * p-exp.y (variable): Update. * m2-exp.y (variable): Update. * go-exp.y (variable): Update. * expprint.c (dump_for_expression): New overload. * expop.h (check_objfile): New overload. (check_constant): New overload. (class var_value_operation): Use block_symbol. <get_symbol>: Rewrite. * eval.c (var_value_operation::evaluate) (var_value_operation::evaluate_funcall) (var_value_operation::evaluate_for_address) (var_value_operation::evaluate_for_address) (var_value_operation::evaluate_with_coercion) (var_value_operation::evaluate_for_sizeof) (var_value_operation::evaluate_for_cast): Update. * d-exp.y (PrimaryExpression): Update. * c-exp.y (variable): Update. * ax-gdb.c (var_value_operation::do_generate_ax): Update. * ada-lang.c (ada_var_value_operation::evaluate_for_cast) (ada_var_value_operation::evaluate) (ada_var_value_operation::resolve) (ada_funcall_operation::resolve): Update. * ada-exp.y (write_var_from_sym, write_object_renaming) (write_ambiguous_var, write_var_or_type, write_name_assoc) (maybe_overload): Update. * ada-exp.h (class ada_var_value_operation) <get_block>: Rewrite.
2021-04-16 00:05:00 +08:00
struct value *val = address_of_variable (var,
std::get<0> (m_storage).block);
return value_cast (lookup_pointer_type (type->target_type ()), val);
}
return evaluate (nullptr, exp, noside);
}
}
/* Helper function for evaluating the size of a type. */
static value *
evaluate_subexp_for_sizeof_base (struct expression *exp, struct type *type)
{
/* FIXME: This should be size_t. */
struct type *size_type = builtin_type (exp->gdbarch)->builtin_int;
/* $5.3.3/2 of the C++ Standard (n3290 draft) says of sizeof:
"When applied to a reference or a reference type, the result is
the size of the referenced type." */
type = check_typedef (type);
if (exp->language_defn->la_language == language_cplus
&& (TYPE_IS_REFERENCE (type)))
type = check_typedef (type->target_type ());
else if (exp->language_defn->la_language == language_fortran
&& type->code () == TYPE_CODE_PTR)
{
/* Dereference Fortran pointer types to allow them for the Fortran
sizeof intrinsic. */
type = check_typedef (type->target_type ());
}
return value_from_longest (size_type, (LONGEST) type->length ());
}
Introduce class operation This patch introduces class operation, the new base class for all expression operations. In the new approach, an operation is simply a class that presents a certain interface. Operations own their operands, and management is done via unique_ptr. The operation interface is largely ad hoc, based on the evolution of expression handling in GDB. Parts (for example, evaluate_with_coercion) are probably redundant; however I took this approach to try to avoid mixing different kinds of refactorings. In some specific situations, rather than add a generic method across the entire operation class hierarchy, I chose instead to use dynamic_cast and specialized methods on certain concrete subclasses. This will appear in some subsequent patches. One goal of this work is to avoid the kinds of easy-to-make errors that affected the old implementation. To this end, some helper subclasses are also added here. These helpers automate the implementation of the 'dump', 'uses_objfile', and 'constant_p' methods. Nearly every concrete operation that is subsequently added will use these facilities. (Note that the 'dump' implementation is only outlined here, the body appears in the next patch.) gdb/ChangeLog 2021-03-08 Tom Tromey <tom@tromey.com> * expression.h (expr::operation): New class. (expr::make_operation): New function. (expr::operation_up): New typedef. * expop.h: New file. * eval.c (operation::evaluate_for_cast) (operation::evaluate_for_address, operation::evaluate_for_sizeof): New methods. * ax-gdb.c (operation::generate_ax): New method.
2021-03-08 22:27:57 +08:00
namespace expr
{
value *
operation::evaluate_for_sizeof (struct expression *exp, enum noside noside)
{
value *val = evaluate (nullptr, exp, EVAL_AVOID_SIDE_EFFECTS);
return evaluate_subexp_for_sizeof_base (exp, val->type ());
Introduce class operation This patch introduces class operation, the new base class for all expression operations. In the new approach, an operation is simply a class that presents a certain interface. Operations own their operands, and management is done via unique_ptr. The operation interface is largely ad hoc, based on the evolution of expression handling in GDB. Parts (for example, evaluate_with_coercion) are probably redundant; however I took this approach to try to avoid mixing different kinds of refactorings. In some specific situations, rather than add a generic method across the entire operation class hierarchy, I chose instead to use dynamic_cast and specialized methods on certain concrete subclasses. This will appear in some subsequent patches. One goal of this work is to avoid the kinds of easy-to-make errors that affected the old implementation. To this end, some helper subclasses are also added here. These helpers automate the implementation of the 'dump', 'uses_objfile', and 'constant_p' methods. Nearly every concrete operation that is subsequently added will use these facilities. (Note that the 'dump' implementation is only outlined here, the body appears in the next patch.) gdb/ChangeLog 2021-03-08 Tom Tromey <tom@tromey.com> * expression.h (expr::operation): New class. (expr::make_operation): New function. (expr::operation_up): New typedef. * expop.h: New file. * eval.c (operation::evaluate_for_cast) (operation::evaluate_for_address, operation::evaluate_for_sizeof): New methods. * ax-gdb.c (operation::generate_ax): New method.
2021-03-08 22:27:57 +08:00
}
value *
var_msym_value_operation::evaluate_for_sizeof (struct expression *exp,
enum noside noside)
{
const bound_minimal_symbol &b = std::get<0> (m_storage);
value *mval = evaluate_var_msym_value (noside, b.objfile, b.minsym);
struct type *type = mval->type ();
if (type->code () == TYPE_CODE_ERROR)
error_unknown_type (b.minsym->print_name ());
/* FIXME: This should be size_t. */
struct type *size_type = builtin_type (exp->gdbarch)->builtin_int;
return value_from_longest (size_type, type->length ());
}
value *
subscript_operation::evaluate_for_sizeof (struct expression *exp,
enum noside noside)
{
if (noside == EVAL_NORMAL)
{
value *val = std::get<0> (m_storage)->evaluate (nullptr, exp,
EVAL_AVOID_SIDE_EFFECTS);
struct type *type = check_typedef (val->type ());
if (type->code () == TYPE_CODE_ARRAY)
{
type = check_typedef (type->target_type ());
if (type->code () == TYPE_CODE_ARRAY)
{
type = type->index_type ();
/* Only re-evaluate the right hand side if the resulting type
is a variable length type. */
if (type->bounds ()->flag_bound_evaluated)
{
val = evaluate (nullptr, exp, EVAL_NORMAL);
/* FIXME: This should be size_t. */
struct type *size_type
= builtin_type (exp->gdbarch)->builtin_int;
return value_from_longest
(size_type, (LONGEST) val->type ()->length ());
}
}
}
}
return operation::evaluate_for_sizeof (exp, noside);
}
value *
unop_ind_base_operation::evaluate_for_sizeof (struct expression *exp,
enum noside noside)
{
value *val = std::get<0> (m_storage)->evaluate (nullptr, exp,
EVAL_AVOID_SIDE_EFFECTS);
struct type *type = check_typedef (val->type ());
if (!type->is_pointer_or_reference ()
&& type->code () != TYPE_CODE_ARRAY)
error (_("Attempt to take contents of a non-pointer value."));
type = type->target_type ();
if (is_dynamic_type (type))
type = value_ind (val)->type ();
/* FIXME: This should be size_t. */
struct type *size_type = builtin_type (exp->gdbarch)->builtin_int;
return value_from_longest (size_type, (LONGEST) type->length ());
}
value *
unop_memval_operation::evaluate_for_sizeof (struct expression *exp,
enum noside noside)
{
return evaluate_subexp_for_sizeof_base (exp, std::get<1> (m_storage));
}
value *
unop_memval_type_operation::evaluate_for_sizeof (struct expression *exp,
enum noside noside)
{
value *typeval = std::get<0> (m_storage)->evaluate (nullptr, exp,
EVAL_AVOID_SIDE_EFFECTS);
return evaluate_subexp_for_sizeof_base (exp, typeval->type ());
}
value *
var_value_operation::evaluate_for_sizeof (struct expression *exp,
enum noside noside)
{
struct type *type = std::get<0> (m_storage).symbol->type ();
if (is_dynamic_type (type))
{
value *val = evaluate (nullptr, exp, EVAL_NORMAL);
type = val->type ();
if (type->code () == TYPE_CODE_ARRAY)
{
/* FIXME: This should be size_t. */
struct type *size_type = builtin_type (exp->gdbarch)->builtin_int;
if (type_not_allocated (type) || type_not_associated (type))
return value::zero (size_type, not_lval);
else if (is_dynamic_type (type->index_type ())
&& !type->bounds ()->high.is_available ())
return value::allocate_optimized_out (size_type);
}
}
return evaluate_subexp_for_sizeof_base (exp, type);
}
value *
var_msym_value_operation::evaluate_for_cast (struct type *to_type,
struct expression *exp,
enum noside noside)
{
if (noside == EVAL_AVOID_SIDE_EFFECTS)
return value::zero (to_type, not_lval);
const bound_minimal_symbol &b = std::get<0> (m_storage);
value *val = evaluate_var_msym_value (noside, b.objfile, b.minsym);
val = value_cast (to_type, val);
/* Don't allow e.g. '&(int)var_with_no_debug_info'. */
if (val->lval () == lval_memory)
{
if (val->lazy ())
val->fetch_lazy ();
val->set_lval (not_lval);
}
return val;
}
value *
var_value_operation::evaluate_for_cast (struct type *to_type,
struct expression *exp,
enum noside noside)
{
value *val = evaluate_var_value (noside,
Use block_symbol in var_value_operation I noticed that var_value_operation takes a block and a symbol, and most callers destructure a block_symbol to pass in. It seems better for this class to simply hold a block_symbol instead. Tested on x86-64 Fedora 32. gdb/ChangeLog 2021-04-15 Tom Tromey <tromey@adacore.com> * rust-exp.y (rust_parser::convert_ast_to_expression): Update. * parse.c (parser_state::push_symbol, parser_state::push_dollar): Update. * p-exp.y (variable): Update. * m2-exp.y (variable): Update. * go-exp.y (variable): Update. * expprint.c (dump_for_expression): New overload. * expop.h (check_objfile): New overload. (check_constant): New overload. (class var_value_operation): Use block_symbol. <get_symbol>: Rewrite. * eval.c (var_value_operation::evaluate) (var_value_operation::evaluate_funcall) (var_value_operation::evaluate_for_address) (var_value_operation::evaluate_for_address) (var_value_operation::evaluate_with_coercion) (var_value_operation::evaluate_for_sizeof) (var_value_operation::evaluate_for_cast): Update. * d-exp.y (PrimaryExpression): Update. * c-exp.y (variable): Update. * ax-gdb.c (var_value_operation::do_generate_ax): Update. * ada-lang.c (ada_var_value_operation::evaluate_for_cast) (ada_var_value_operation::evaluate) (ada_var_value_operation::resolve) (ada_funcall_operation::resolve): Update. * ada-exp.y (write_var_from_sym, write_object_renaming) (write_ambiguous_var, write_var_or_type, write_name_assoc) (maybe_overload): Update. * ada-exp.h (class ada_var_value_operation) <get_block>: Rewrite.
2021-04-16 00:05:00 +08:00
std::get<0> (m_storage).block,
std::get<0> (m_storage).symbol);
val = value_cast (to_type, val);
/* Don't allow e.g. '&(int)var_with_no_debug_info'. */
if (val->lval () == lval_memory)
{
if (val->lazy ())
val->fetch_lazy ();
val->set_lval (not_lval);
}
return val;
}
}
2011-01-07 Michael Snyder <msnyder@vmware.com> * ada-lang.c: Comment cleanup, mostly periods and spaces. * ada-lang.h: Ditto. * ada-tasks.c: Ditto. * ada-valprint.c: Ditto. * aix-threads.c: Ditto. * alpha-linux-nat.c: Ditto. * alpha-linux-tdep.c: Ditto. * alpha-mdebug-tdep.c: Ditto. * alpha-nat.c: Ditto. * alpha-osf1-tdep.c: Ditto. * alpha-tdep.c: Ditto. * alphabsd-nat.c: Ditto. * alphabsd-tdep.c: Ditto. * amd64-darwin-tdep.c: Ditto. * amd64-linux-nat.c: Ditto. * amd64-linux-tdep.c: Ditto. * amd64-sol2-tdep.c: Ditto. * amd64-tdep.c: Ditto. * amd64-fbsd-tdep.c: Ditto. * amd64-nbsd-tdep.c: Ditto. * amd64-obsd-tdep.c: Ditto. * amd64-linux-nat.c: Ditto. * amd64-linux-tdep.c: Ditto. * arm-tdep.c: Ditto. * arm-tdep.h: Ditto. * armnbsd-nat.c: Ditto. * avr-tdep.c: Ditto. * bfin-tdep.c: Ditto. * bsd-kvm.c: Ditto. * c-typeprintc: Ditto. * c-valprint.c: Ditto. * coff-pe-read.h: Ditto. * coffreead.c: Ditto. * cris-tdep.c: Ditto. * d-lang.c: Ditto. * darwin-nat-info.c: Ditto. * darwin-nat.c: Ditto. * dbug-rom.c: Ditto. * dbxread.c: Ditto. * dcache.c: Ditto. * dcache.h: Ditto. * dec-thread.c: Ditto. * defs.h: Ditto. * demangle.c: Ditto. * dicos-tdep.c: Ditto. * dictionary.c: Ditto. * dictionary.h: Ditto. * dink32-rom.c: Ditto. * disasm.c: Ditto. * doublest.c: Ditto. * dsrec.c: Ditto. * dummy-frame.c: Ditto. * dwarf2-frame.c: Ditto. * dwarf2expr.c: Ditto. * dwarf2loc.c: Ditto. * dwarf2read.c: Ditto. * elfread.c: Ditto. * environ.c: Ditto. * eval.c: Ditto. * event-top.h: Ditto. * exceptions.c: Ditto. * exceptions.h: Ditto. * exec.c: Ditto. * expprint.c: Ditto. * expression.h: Ditto. * f-exp.y: Ditto. * f-lang.c: Ditto. * f-lang.h: Ditto. * f-typeprint.c: Ditto. * f-valprint.c: Ditto. * fbsd-nat.c: Ditto. * findvar.c: Ditto. * fork-child.c: Ditto. * frame.c: Ditto. * frame.h: Ditto. * frv-linux-tdep.c: Ditto. * frv-tdep.c: Ditto. * gcore.c: Ditto. * gdb-stabs.h: Ditto. * gdb_assert.h: Ditto. * gdb_string.h: Ditto. * gdb_thread_db.h: Ditto. * gdb_wait.h: Ditto. * gdbarch.sh: Ditto. * gdbcore.h: Ditto. * gdbthread.h: Ditto. * gdbtypes.c: Ditto. * gdbtypes.h: Ditto. * gnu-nat.c: Ditto. * gnu-nat.h: Ditto. * gnu-v2-abi.c: Ditto. * gnu-v3-abi.c: Ditto. * go32-nat.c: Ditto. * gdbarch.c: Regenerate. * gdbarch.h: Regenerate.
2011-01-08 03:36:19 +08:00
/* Parse a type expression in the string [P..P+LENGTH). */
struct type *
parse_and_eval_type (const char *p, int length)
{
1999-07-08 04:19:36 +08:00
char *tmp = (char *) alloca (length + 4);
1999-07-08 04:19:36 +08:00
tmp[0] = '(';
memcpy (tmp + 1, p, length);
tmp[length + 1] = ')';
tmp[length + 2] = '0';
tmp[length + 3] = '\0';
'struct expression *' -> gdb::unique_xmalloc_ptr<expression> This patch makes parse_expression and friends return a unique_ptr instead of raw pointer [1]: typedef gdb::unique_malloc_ptr<expression> expression_up; and then adjusts the codebase throughout to stop using cleanups to manage lifetime of expression pointers. Whenever I found a structure owning an expression pointer, I made it store a unique_ptr instead of a raw pointer, which then requires using new/delete of the holding structure, instead of XNEW/xfree. [1] - I'd like to set the rule that types named with an "_up" suffix are unique_ptr typedefs. Note I used gdb::unique_xmalloc_ptr instead of gdb::unique_ptr, simply because we still use xmalloc instead of new to allocate expression objects. Once that's changed, all we need to do is change the expression_up typedef and the smart pointer will then call delete instead of xfree. gdb/ChangeLog: 2016-11-08 Pedro Alves <palves@redhat.com> * ada-lang.c (ada_read_renaming_var_value): Use expression_up. (struct ada_catchpoint_location) <excep_cond_expr>: Now an expression_up. (ada_catchpoint_location_dtor): Reset excep_cond_expr instead of using xfree. (create_excep_cond_exprs): Use expression_up and gdb::move. (allocate_location_exception): Use new instead of XNEW. (should_stop_exception): Likewise. Adjust to use expression_up. (create_ada_exception_catchpoint): Use new instead of XNEW. * ax-gdb.c (agent_eval_command_one): Use expression_up instead of cleanups. (maint_agent_printf_command): Use expression_up. * break-catch-sig.c (create_signal_catchpoint): Use new instead of XNEW. * break-catch-syscall.c (create_syscall_event_catchpoint): Likewise. * break-catch-throw.c (handle_gnu_v3_exceptions): Use new instead of XCNEW. Use gdb::unique_ptr instead of cleanups. * breakpoint.c (set_breakpoint_condition, update_watchpoint) (parse_cmd_to_aexpr, watchpoint_check) (bpstat_check_breakpoint_conditions, watchpoint_locations_match): Adjust to use expression_up. (init_bp_location): Adjust. (free_bp_location): Use delete instead of xfree. (set_raw_breakpoint_without_location, set_raw_breakpoint) (add_solib_catchpoint, create_fork_vfork_event_catchpoint) (new_single_step_breakpoint, create_breakpoint_sal): Use new instead of XNEW. (find_condition_and_thread): Adjust to use expression_up. (create_breakpoint): Use new instead of XNEW. (dtor_watchpoint): Don't xfree expression pointers, they're unique_ptr's now. (insert_watchpoint, remove_watchpoint): Adjust. (watch_command_1): Use expression_up. Use new instead of XCNEW. (catch_exec_command_1): Use new instead of XNEW. (bp_location_dtor): Don't xfree expression pointers, they're unique_ptr's now. (base_breakpoint_allocate_location) (strace_marker_create_breakpoints_sal): Use new instead of XNEW. (delete_breakpoint): Use delete instead of xfree. * breakpoint.h (struct bp_location) <cond>: Now an unique_ptr<expression> instead of a raw pointer. (struct watchpoint) <exp, cond_exp>: Likewise. * cli/cli-script.c (execute_control_command): Use expression_up instead of cleanups. * dtrace-probe.c (dtrace_process_dof_probe): Use expression_up. * eval.c (parse_and_eval_address, parse_and_eval_long) (parse_and_eval, parse_to_comma_and_eval, parse_and_eval_type): Use expression_up instead of cleanups. * expression.h (expression_up): New typedef. (parse_expression, parse_expression_with_language, parse_exp_1): Change return type to expression_up. * mi/mi-main.c (mi_cmd_data_evaluate_expression) (print_variable_or_computed): Use expression_up. * objc-lang.c (print_object_command): Use expression_up instead of cleanups. * parse.c (parse_exp_1, parse_exp_in_context) (parse_exp_in_context_1, parse_expression) (parse_expression_with_language): Return an expression_up instead of a raw pointer. (parse_expression_for_completion): Use expression_up. * printcmd.c (struct display) <exp>: Now an expression_up instead of a raw pointer. (print_command_1, output_command_const, set_command, x_command): Use expression_up instead of cleanups. (display_command): Likewise. Use new instead of XNEW. (free_display): Use delete instead of xfree. (do_one_display): Adjust to use expression_up. * remote.c (remote_download_tracepoint): Likewise. * stack.c (return_command): Likewise. * tracepoint.c (validate_actionline, encode_actions_1): Use expression_up instead of cleanups. * typeprint.c (whatis_exp, maintenance_print_type): Likewise. * value.c (init_if_undefined_command): Likewise. * varobj.c (struct varobj_root) <exp>: Now an expression_up instead of a raw pointer. (varobj_create): Adjust. (varobj_set_value): Use an expression_up instead of cleanups. (new_root_variable): Use new instead of XNEW. (free_variable): Use delete instead of xfree. (value_of_root_1): Use std::swap.
2016-11-08 23:26:43 +08:00
expression_up expr = parse_expression (tmp);
Remove union exp_element This removes union exp_element functions that either create such elements or walk them. struct expression no longer holds exp_elements. A couple of language_defn methods are also removed, as they are obsolete. Note that this patch also removes the print_expression code. The only in-tree caller of this was from dump_prefix_expression, which is only called when expression debugging is enabled. Implementing this would involve a fair amount of code, and it seems to me that prefix dumping is preferable anyway, as it is unambiguous. So, I have not reimplemented this feature. gdb/ChangeLog 2021-03-08 Tom Tromey <tom@tromey.com> * value.h (evaluate_subexp_with_coercion): Don't declare. * parse.c (exp_descriptor_standard): Remove. (expr_builder::expr_builder, expr_builder::release): Update. (expression::expression): Remove size_t parameter. (expression::~expression): Simplify. (expression::resize): Remove. (write_exp_elt, write_exp_elt_opcode, write_exp_elt_sym) (write_exp_elt_msym, write_exp_elt_block, write_exp_elt_objfile) (write_exp_elt_longcst, write_exp_elt_floatcst) (write_exp_elt_type, write_exp_elt_intern, write_exp_string) (write_exp_string_vector, write_exp_bitstring): Remove. * p-lang.h (class pascal_language) <opcode_print_table, op_print_tab>: Remove. * p-lang.c (pascal_language::op_print_tab): Remove. * opencl-lang.c (class opencl_language) <opcode_print_table>: Remove. * objc-lang.c (objc_op_print_tab): Remove. (class objc_language) <opcode_print_table>: Remove. * m2-lang.h (class m2_language) <opcode_print_table, op_print_tab>: Remove. * m2-lang.c (m2_language::op_print_tab): Remove. * language.h (struct language_defn) <post_parser, expression_ops, opcode_print_table>: Remove. * language.c (language_defn::expression_ops) (auto_or_unknown_language::opcode_print_table): Remove. * go-lang.h (class go_language) <opcode_print_table, op_print_tab>: Remove. * go-lang.c (go_language::op_print_tab): Remove. * f-lang.h (class f_language) <opcode_print_table>: Remove <op_print_tab>: Remove. * f-lang.c (f_language::op_print_tab): Remove. * expression.h (union exp_element): Remove. (struct expression): Remove size_t parameter from constructor. <resize>: Remove. <first_opcode>: Update. <nelts, elts>: Remove. (EXP_ELEM_TO_BYTES, BYTES_TO_EXP_ELEM): Remove. (evaluate_subexp_standard, print_expression, op_string) (dump_raw_expression): Don't declare. * expprint.c (print_expression, print_subexp) (print_subexp_funcall, print_subexp_standard, op_string) (dump_raw_expression, dump_subexp, dump_subexp_body) (dump_subexp_body_funcall, dump_subexp_body_standard): Remove. (dump_prefix_expression): Update. * eval.c (evaluate_subexp): Remove. (evaluate_expression, evaluate_type): Update. (evaluate_subexpression_type): Remove. (fetch_subexp_value): Remove "pc" parameter. Update. (extract_field_op, evaluate_struct_tuple, evaluate_funcall) (evaluate_subexp_standard, evaluate_subexp_for_address) (evaluate_subexp_with_coercion, evaluate_subexp_for_sizeof) (evaluate_subexp_for_cast): Remove. (parse_and_eval_type): Update. * dtrace-probe.c (dtrace_probe::compile_to_ax): Update. * d-lang.c (d_op_print_tab): Remove. (class d_language) <opcode_print_table>: Remove. * c-lang.h (c_op_print_tab): Don't declare. * c-lang.c (c_op_print_tab): Remove. (class c_language, class cplus_language, class asm_language, class minimal_language) <opcode_print_table>: Remove. * breakpoint.c (update_watchpoint, watchpoint_check) (watchpoint_exp_is_const, watch_command_1): Update. * ax-gdb.h (union exp_element): Don't declare. * ax-gdb.c (const_var_ref, const_expr, maybe_const_expr) (gen_repeat, gen_sizeof, gen_expr_for_cast, gen_expr) (gen_expr_binop_rest): Remove. (gen_trace_for_expr, gen_eval_for_expr, gen_printf): Update. * ada-lang.c (ada_op_print_tab): Remove. (class ada_language) <post_parser, opcode_print_table>: Remove.
2021-03-08 22:27:57 +08:00
expr::unop_cast_operation *op
= dynamic_cast<expr::unop_cast_operation *> (expr->op.get ());
if (op == nullptr)
2005-02-10 Andrew Cagney <cagney@gnu.org> Mark up all error and warning messages. * ada-lang.c, amd64-tdep.c, arch-utils.c, breakpoint.c: Update. * bsd-kvm.c, bsd-uthread.c, coff-solib.h, coffread.c: Update. * core-aout.c, core-regset.c, corefile.c, corelow.c: Update. * cp-abi.c, cp-support.c, cp-valprint.c, cris-tdep.c: Update. * dbxread.c, demangle.c, doublest.c, dsrec.c: Update. * dve3900-rom.c, dwarf2expr.c, dwarf2loc.c: Update. * dwarf2read.c, dwarfread.c, elfread.c, eval.c: Update. * event-top.c, exec.c, expprint.c, f-lang.c: Update. * f-typeprint.c, f-valprint.c, fbsd-nat.c, findvar.c: Update. * frame.c, frv-linux-tdep.c, gcore.c, gdbtypes.c: Update. * gnu-nat.c, gnu-v2-abi.c, gnu-v3-abi.c, go32-nat.c: Update. * hpacc-abi.c, hppa-hpux-nat.c, hppa-hpux-tdep.c: Update. * hppa-linux-nat.c, hppa-linux-tdep.c, hppa-tdep.c: Update. * hpread.c, hpux-thread.c, i386-linux-nat.c: Update. * i386-linux-tdep.c, i386-tdep.c, i386bsd-nat.c: Update. * i386gnu-nat.c, i387-tdep.c, ia64-linux-nat.c: Update. * ia64-tdep.c, inf-child.c, inf-ptrace.c, inf-ttrace.c: Update. * infcall.c, infcmd.c, inflow.c, infptrace.c, infrun.c: Update. * inftarg.c, interps.c, irix5-nat.c, jv-lang.c: Update. * kod-cisco.c, kod.c, language.c, libunwind-frame.c: Update. * linespec.c, linux-nat.c, linux-thread-db.c, m2-lang.c: Update. * m32r-rom.c, m68hc11-tdep.c, m68k-tdep.c: Update. * m68klinux-nat.c, macrocmd.c, macroexp.c, main.c: Update. * maint.c, mdebugread.c, mem-break.c, memattr.c: Update. * mips-linux-tdep.c, mips-tdep.c, mipsread.c, monitor.c: Update. * nlmread.c, nto-procfs.c, objc-lang.c, objfiles.c: Update. * observer.c, ocd.c, p-lang.c, p-typeprint.c: Update. * p-valprint.c, pa64solib.c, parse.c, ppc-linux-tdep.c: Update. * ppcnbsd-tdep.c, printcmd.c, procfs.c, remote-e7000.c: Update. * remote-fileio.c, remote-m32r-sdi.c, remote-rdi.c: Update. * remote-rdp.c, remote-sim.c, remote-st.c: Update. * remote-utils.c, remote-utils.h, remote.c: Update. * rom68k-rom.c, rs6000-nat.c, s390-tdep.c, scm-lang.c: Update. * ser-e7kpc.c, ser-tcp.c, ser-unix.c, sh-tdep.c: Update. * sh3-rom.c, shnbsd-tdep.c, sol-thread.c, solib-aix5.c: Update. * solib-frv.c, solib-irix.c, solib-osf.c, solib-pa64.c: Update. * solib-som.c, solib-sunos.c, solib-svr4.c, solib.c: Update. * somread.c, somsolib.c, source.c, stabsread.c: Update. * stack.c, std-regs.c, symfile-mem.c, symfile.c: Update. * symmisc.c, symtab.c, target.c, thread.c, top.c: Update. * tracepoint.c, trad-frame.c, typeprint.c, utils.c: Update. * uw-thread.c, valarith.c, valops.c, valprint.c: Update. * value.c, varobj.c, version.in, win32-nat.c, wince.c: Update. * xcoffread.c, xcoffsolib.c, cli/cli-cmds.c: Update. * cli/cli-decode.c, cli/cli-dump.c, cli/cli-logging.c: Update. * cli/cli-script.c, cli/cli-setshow.c, mi/mi-cmd-break.c: Update. * mi/mi-cmd-disas.c, mi/mi-cmd-env.c, mi/mi-cmd-file.c: Update. * mi/mi-cmd-stack.c, mi/mi-cmd-var.c, mi/mi-getopt.c: Update. * mi/mi-symbol-cmds.c, tui/tui-layout.c, tui/tui-stack.c: Update. * tui/tui-win.c: Update.
2005-02-11 12:06:14 +08:00
error (_("Internal error in eval_type."));
Remove union exp_element This removes union exp_element functions that either create such elements or walk them. struct expression no longer holds exp_elements. A couple of language_defn methods are also removed, as they are obsolete. Note that this patch also removes the print_expression code. The only in-tree caller of this was from dump_prefix_expression, which is only called when expression debugging is enabled. Implementing this would involve a fair amount of code, and it seems to me that prefix dumping is preferable anyway, as it is unambiguous. So, I have not reimplemented this feature. gdb/ChangeLog 2021-03-08 Tom Tromey <tom@tromey.com> * value.h (evaluate_subexp_with_coercion): Don't declare. * parse.c (exp_descriptor_standard): Remove. (expr_builder::expr_builder, expr_builder::release): Update. (expression::expression): Remove size_t parameter. (expression::~expression): Simplify. (expression::resize): Remove. (write_exp_elt, write_exp_elt_opcode, write_exp_elt_sym) (write_exp_elt_msym, write_exp_elt_block, write_exp_elt_objfile) (write_exp_elt_longcst, write_exp_elt_floatcst) (write_exp_elt_type, write_exp_elt_intern, write_exp_string) (write_exp_string_vector, write_exp_bitstring): Remove. * p-lang.h (class pascal_language) <opcode_print_table, op_print_tab>: Remove. * p-lang.c (pascal_language::op_print_tab): Remove. * opencl-lang.c (class opencl_language) <opcode_print_table>: Remove. * objc-lang.c (objc_op_print_tab): Remove. (class objc_language) <opcode_print_table>: Remove. * m2-lang.h (class m2_language) <opcode_print_table, op_print_tab>: Remove. * m2-lang.c (m2_language::op_print_tab): Remove. * language.h (struct language_defn) <post_parser, expression_ops, opcode_print_table>: Remove. * language.c (language_defn::expression_ops) (auto_or_unknown_language::opcode_print_table): Remove. * go-lang.h (class go_language) <opcode_print_table, op_print_tab>: Remove. * go-lang.c (go_language::op_print_tab): Remove. * f-lang.h (class f_language) <opcode_print_table>: Remove <op_print_tab>: Remove. * f-lang.c (f_language::op_print_tab): Remove. * expression.h (union exp_element): Remove. (struct expression): Remove size_t parameter from constructor. <resize>: Remove. <first_opcode>: Update. <nelts, elts>: Remove. (EXP_ELEM_TO_BYTES, BYTES_TO_EXP_ELEM): Remove. (evaluate_subexp_standard, print_expression, op_string) (dump_raw_expression): Don't declare. * expprint.c (print_expression, print_subexp) (print_subexp_funcall, print_subexp_standard, op_string) (dump_raw_expression, dump_subexp, dump_subexp_body) (dump_subexp_body_funcall, dump_subexp_body_standard): Remove. (dump_prefix_expression): Update. * eval.c (evaluate_subexp): Remove. (evaluate_expression, evaluate_type): Update. (evaluate_subexpression_type): Remove. (fetch_subexp_value): Remove "pc" parameter. Update. (extract_field_op, evaluate_struct_tuple, evaluate_funcall) (evaluate_subexp_standard, evaluate_subexp_for_address) (evaluate_subexp_with_coercion, evaluate_subexp_for_sizeof) (evaluate_subexp_for_cast): Remove. (parse_and_eval_type): Update. * dtrace-probe.c (dtrace_probe::compile_to_ax): Update. * d-lang.c (d_op_print_tab): Remove. (class d_language) <opcode_print_table>: Remove. * c-lang.h (c_op_print_tab): Don't declare. * c-lang.c (c_op_print_tab): Remove. (class c_language, class cplus_language, class asm_language, class minimal_language) <opcode_print_table>: Remove. * breakpoint.c (update_watchpoint, watchpoint_check) (watchpoint_exp_is_const, watch_command_1): Update. * ax-gdb.h (union exp_element): Don't declare. * ax-gdb.c (const_var_ref, const_expr, maybe_const_expr) (gen_repeat, gen_sizeof, gen_expr_for_cast, gen_expr) (gen_expr_binop_rest): Remove. (gen_trace_for_expr, gen_eval_for_expr, gen_printf): Update. * ada-lang.c (ada_op_print_tab): Remove. (class ada_language) <post_parser, opcode_print_table>: Remove.
2021-03-08 22:27:57 +08:00
return op->get_type ();
}