aboutsummaryrefslogtreecommitdiff
path: root/gdb/dwarf2/cooked-index-entry.h
diff options
context:
space:
mode:
Diffstat (limited to 'gdb/dwarf2/cooked-index-entry.h')
-rw-r--r--gdb/dwarf2/cooked-index-entry.h258
1 files changed, 258 insertions, 0 deletions
diff --git a/gdb/dwarf2/cooked-index-entry.h b/gdb/dwarf2/cooked-index-entry.h
new file mode 100644
index 0000000..bb47e32
--- /dev/null
+++ b/gdb/dwarf2/cooked-index-entry.h
@@ -0,0 +1,258 @@
+/* Entry in the cooked index
+
+ Copyright (C) 2022-2024 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 <http://www.gnu.org/licenses/>. */
+
+#ifndef GDB_DWARF2_COOKED_INDEX_ENTRY_H
+#define GDB_DWARF2_COOKED_INDEX_ENTRY_H
+
+#include "dwarf2/parent-map.h"
+#include "dwarf2/types.h"
+#include "symtab.h"
+#include "gdbsupport/gdb_obstack.h"
+#include "quick-symbol.h"
+
+/* Flags that describe an entry in the index. */
+enum cooked_index_flag_enum : unsigned char
+{
+ /* True if this entry is the program's "main". */
+ IS_MAIN = 1,
+ /* True if this entry represents a "static" object. */
+ IS_STATIC = 2,
+ /* True if this entry uses the linkage name. */
+ IS_LINKAGE = 4,
+ /* True if this entry is just for the declaration of a type, not the
+ definition. */
+ IS_TYPE_DECLARATION = 8,
+ /* True is parent_entry.deferred has a value rather than parent_entry
+ .resolved. */
+ IS_PARENT_DEFERRED = 16,
+ /* True if this entry was synthesized by gdb (as opposed to coming
+ directly from the DWARF). */
+ IS_SYNTHESIZED = 32,
+};
+DEF_ENUM_FLAGS_TYPE (enum cooked_index_flag_enum, cooked_index_flag);
+
+/* Flags used when requesting the full name of an entry. */
+enum cooked_index_full_name_enum : unsigned char
+{
+ /* Set when requesting the name of "main". See the method for the
+ full description. */
+ FOR_MAIN = 1,
+ /* Set when requesting the linkage name for an Ada entry. */
+ FOR_ADA_LINKAGE_NAME = 2,
+};
+DEF_ENUM_FLAGS_TYPE (enum cooked_index_full_name_enum, cooked_index_full_name_flag);
+
+/* Type representing either a resolved or deferred cooked_index_entry. */
+
+union cooked_index_entry_ref
+{
+ cooked_index_entry_ref (parent_map::addr_type deferred_)
+ {
+ deferred = deferred_;
+ }
+
+ cooked_index_entry_ref (const cooked_index_entry *resolved_)
+ {
+ resolved = resolved_;
+ }
+
+ const cooked_index_entry *resolved;
+ parent_map::addr_type deferred;
+};
+
+/* Return a string representation of FLAGS. */
+
+std::string to_string (cooked_index_flag flags);
+
+/* A cooked_index_entry represents a single item in the index. Note
+ that two entries can be created for the same DIE -- one using the
+ name, and another one using the linkage name, if any.
+
+ This is an "open" class and the members are all directly
+ accessible. It is read-only after the index has been fully read
+ and processed. */
+struct cooked_index_entry : public allocate_on_obstack<cooked_index_entry>
+{
+ cooked_index_entry (sect_offset die_offset_, enum dwarf_tag tag_,
+ cooked_index_flag flags_,
+ enum language lang_, const char *name_,
+ cooked_index_entry_ref parent_entry_,
+ dwarf2_per_cu *per_cu_)
+ : name (name_),
+ tag (tag_),
+ flags (flags_),
+ lang (lang_),
+ die_offset (die_offset_),
+ per_cu (per_cu_),
+ m_parent_entry (parent_entry_)
+ {
+ }
+
+ /* Return true if this entry matches SEARCH_FLAGS. */
+ bool matches (block_search_flags search_flags) const
+ {
+ /* Just reject type declarations. */
+ if ((flags & IS_TYPE_DECLARATION) != 0)
+ return false;
+
+ if ((search_flags & SEARCH_STATIC_BLOCK) != 0
+ && (flags & IS_STATIC) != 0)
+ return true;
+ if ((search_flags & SEARCH_GLOBAL_BLOCK) != 0
+ && (flags & IS_STATIC) == 0)
+ return true;
+ return false;
+ }
+
+ /* Return true if this entry matches KIND. */
+ bool matches (domain_search_flags kind) const;
+
+ /* Construct the fully-qualified name of this entry and return a
+ pointer to it. If allocation is needed, it will be done on
+ STORAGE.
+
+ FLAGS affects the result. If the FOR_MAIN flag is set, we are
+ computing the name of the "main" entry -- one marked
+ DW_AT_main_subprogram. This matters for avoiding name
+ canonicalization and also a related race (if "main" computation
+ is done during finalization).
+
+ If the FOR_ADA_LINKAGE_NAME flag is set, then Ada-language
+ symbols will have their "linkage-style" name computed. The
+ default is source-style.
+
+ If the language doesn't prescribe a separator, one can be
+ specified using DEFAULT_SEP. */
+ const char *full_name (struct obstack *storage,
+ cooked_index_full_name_flag name_flags = 0,
+ const char *default_sep = nullptr) const;
+
+ /* Comparison modes for the 'compare' function. See the function
+ for a description. */
+ enum comparison_mode
+ {
+ MATCH,
+ SORT,
+ COMPLETE,
+ };
+
+ /* Compare two strings, case-insensitively. Return -1 if STRA is
+ less than STRB, 0 if they are equal, and 1 if STRA is greater.
+
+ When comparing, '<' is considered to be less than all other
+ printable characters. This ensures that "t<x>" sorts before
+ "t1", which is necessary when looking up "t". This '<' handling
+ is to ensure that certain C++ lookups work correctly. It is
+ inexact, and applied regardless of the search language, but this
+ is ok because callers of this code do more precise filtering
+ according to their needs. This is also why using a
+ case-insensitive comparison works even for languages that are
+ case sensitive.
+
+ MODE controls how the comparison proceeds.
+
+ MODE==SORT is used when sorting and the only special '<' handling
+ that it does is to ensure that '<' sorts before all other
+ printable characters. This ensures that the resulting ordering
+ will be binary-searchable.
+
+ MODE==MATCH is used when searching for a symbol. In this case,
+ STRB must always be the search name, and STRA must be the name in
+ the index that is under consideration. In compare mode, early
+ termination of STRB may match STRA -- for example, "t<int>" and
+ "t" will be considered to be equal. (However, if A=="t" and
+ B=="t<int>", then this will not consider them as equal.)
+
+ MODE==COMPLETE is used when searching for a symbol for
+ completion. In this case, STRB must always be the search name,
+ and STRA must be the name in the index that is under
+ consideration. In completion mode, early termination of STRB
+ always results in a match. */
+ static int compare (const char *stra, const char *strb,
+ comparison_mode mode);
+
+ /* Compare two entries by canonical name. */
+ bool operator< (const cooked_index_entry &other) const
+ {
+ return compare (canonical, other.canonical, SORT) < 0;
+ }
+
+ /* Set parent entry to PARENT. */
+ void set_parent (const cooked_index_entry *parent)
+ {
+ gdb_assert ((flags & IS_PARENT_DEFERRED) == 0);
+ m_parent_entry.resolved = parent;
+ }
+
+ /* Resolve deferred parent entry to PARENT. */
+ void resolve_parent (const cooked_index_entry *parent)
+ {
+ gdb_assert ((flags & IS_PARENT_DEFERRED) != 0);
+ flags = flags & ~IS_PARENT_DEFERRED;
+ m_parent_entry.resolved = parent;
+ }
+
+ /* Return parent entry. */
+ const cooked_index_entry *get_parent () const
+ {
+ gdb_assert ((flags & IS_PARENT_DEFERRED) == 0);
+ return m_parent_entry.resolved;
+ }
+
+ /* Return deferred parent entry. */
+ parent_map::addr_type get_deferred_parent () const
+ {
+ gdb_assert ((flags & IS_PARENT_DEFERRED) != 0);
+ return m_parent_entry.deferred;
+ }
+
+ /* The name as it appears in DWARF. This always points into one of
+ the mapped DWARF sections. Note that this may be the name or the
+ linkage name -- two entries are created for DIEs which have both
+ attributes. */
+ const char *name;
+ /* The canonical name. This may be equal to NAME. */
+ const char *canonical = nullptr;
+ /* The DWARF tag. */
+ enum dwarf_tag tag;
+ /* Any flags attached to this entry. */
+ cooked_index_flag flags;
+ /* The language of this symbol. */
+ ENUM_BITFIELD (language) lang : LANGUAGE_BITS;
+ /* The offset of this DIE. */
+ sect_offset die_offset;
+ /* The CU from which this entry originates. */
+ dwarf2_per_cu *per_cu;
+
+private:
+
+ /* A helper method for full_name. Emits the full scope of this
+ object, followed by the separator, to STORAGE. If this entry has
+ a parent, its write_scope method is called first. See full_name
+ for a description of the FLAGS parameter. */
+ void write_scope (struct obstack *storage, const char *sep,
+ cooked_index_full_name_flag flags) const;
+
+ /* The parent entry. This is NULL for top-level entries.
+ Otherwise, it points to the parent entry, such as a namespace or
+ class. */
+ cooked_index_entry_ref m_parent_entry;
+};
+
+#endif /* GDB_DWARF2_COOKED_INDEX_ENTRY_H */