From b2bc564fe817f857b4915903f16026472acfbdcc Mon Sep 17 00:00:00 2001 From: Tom Tromey Date: Sun, 21 Mar 2021 11:07:28 -0600 Subject: [PATCH] Add name splitting The new DWARF index code works by keeping names pre-split. That is, rather than storing a symbol name like "a::b::c", the names "a", "b", and "c" will be stored separately. This patch introduces some helper code to split a full name into its components. --- gdb/Makefile.in | 2 ++ gdb/split-name.c | 81 ++++++++++++++++++++++++++++++++++++++++++++++++ gdb/split-name.h | 45 +++++++++++++++++++++++++++ gdb/symtab.h | 37 ++++++++++++++++++++++ 4 files changed, 165 insertions(+) create mode 100644 gdb/split-name.c create mode 100644 gdb/split-name.h diff --git a/gdb/Makefile.in b/gdb/Makefile.in index 647f012ad4f..110c157896d 100644 --- a/gdb/Makefile.in +++ b/gdb/Makefile.in @@ -1160,6 +1160,7 @@ COMMON_SFILES = \ solib-target.c \ source.c \ source-cache.c \ + split-name.c \ stabsread.c \ stack.c \ std-regs.c \ @@ -1448,6 +1449,7 @@ HFILES_NO_SRCDIR = \ sparc-ravenscar-thread.h \ sparc-tdep.h \ sparc64-tdep.h \ + split-name.h \ stabsread.h \ stack.h \ stap-probe.h \ diff --git a/gdb/split-name.c b/gdb/split-name.c new file mode 100644 index 00000000000..35fe0fe20e7 --- /dev/null +++ b/gdb/split-name.c @@ -0,0 +1,81 @@ +/* Split a symbol name. + + Copyright (C) 2022 Free Software Foundation, Inc. + + This file is part of GDB. + + 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 + (at your option) any later version. + + 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. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +#include "defs.h" +#include "split-name.h" +#include "cp-support.h" + +/* See split-name.h. */ + +std::vector +split_name (const char *name, split_style style) +{ + std::vector result; + unsigned int previous_len = 0; + + switch (style) + { + case split_style::CXX: + for (unsigned int current_len = cp_find_first_component (name); + name[current_len] != '\0'; + current_len += cp_find_first_component (name + current_len)) + { + gdb_assert (name[current_len] == ':'); + result.emplace_back (&name[previous_len], + current_len - previous_len); + /* Skip the '::'. */ + current_len += 2; + previous_len = current_len; + } + break; + + case split_style::UNDERSCORE: + /* Handle the Ada encoded (aka mangled) form here. */ + for (const char *iter = strstr (name, "__"); + iter != nullptr; + iter = strstr (iter, "__")) + { + result.emplace_back (&name[previous_len], + iter - &name[previous_len]); + iter += 2; + previous_len = iter - name; + } + break; + + case split_style::DOT: + /* D and Go-style names. */ + for (const char *iter = strchr (name, '.'); + iter != nullptr; + iter = strchr (iter, '.')) + { + result.emplace_back (&name[previous_len], + iter - &name[previous_len]); + ++iter; + previous_len = iter - name; + } + break; + + default: + break; + } + + result.emplace_back (&name[previous_len]); + return result; +} + diff --git a/gdb/split-name.h b/gdb/split-name.h new file mode 100644 index 00000000000..c588b84f653 --- /dev/null +++ b/gdb/split-name.h @@ -0,0 +1,45 @@ +/* Split a symbol name. + + Copyright (C) 2022 Free Software Foundation, Inc. + + This file is part of GDB. + + 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 + (at your option) any later version. + + 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. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +#ifndef GDB_SPLIT_NAME_H +#define GDB_SPLIT_NAME_H + +#include "gdbsupport/gdb_string_view.h" + +/* The available styles of name splitting. */ + +enum class split_style +{ + /* No splitting - C style. */ + NONE, + /* C++ style, with "::" and template parameter intelligence. */ + CXX, + /* Split at ".". Used by Ada, Go, D. */ + DOT, + /* Split at "__". Used by Ada encoded names. */ + UNDERSCORE, +}; + +/* Split NAME into components at module boundaries. STYLE indicates + which style of splitting to use. */ + +extern std::vector split_name (const char *name, + split_style style); + +#endif /* GDB_SPLIT_NAME_H */ diff --git a/gdb/symtab.h b/gdb/symtab.h index 11e89959e09..4a33c7a119f 100644 --- a/gdb/symtab.h +++ b/gdb/symtab.h @@ -36,6 +36,7 @@ #include "gdbsupport/iterator-range.h" #include "completer.h" #include "gdb-demangle.h" +#include "split-name.h" /* Opaque declarations. */ struct ui_file; @@ -121,6 +122,21 @@ class ada_lookup_name_info final bool verbatim_p () const { return m_verbatim_p; } + /* A wrapper for ::split_name that handles some Ada-specific + peculiarities. */ + std::vector split_name () const + { + if (m_verbatim_p || m_standard_p) + { + std::vector result; + if (m_standard_p) + result.emplace_back ("standard"); + result.emplace_back (m_encoded_name); + return result; + } + return ::split_name (m_encoded_name.c_str (), split_style::UNDERSCORE); + } + private: /* The Ada-encoded lookup name. */ std::string m_encoded_name; @@ -272,6 +288,27 @@ class lookup_name_info final } } + /* A wrapper for ::split_name (see split-name.h) that splits this + name, and that handles any language-specific peculiarities. */ + std::vector split_name (language lang) const + { + if (lang == language_ada) + return ada ().split_name (); + split_style style = split_style::NONE; + switch (lang) + { + case language_cplus: + case language_rust: + style = split_style::CXX; + break; + case language_d: + case language_go: + style = split_style::DOT; + break; + } + return ::split_name (language_lookup_name (lang), style); + } + /* Get the Ada-specific lookup info. */ const ada_lookup_name_info &ada () const { -- 2.30.2