| /* Entry in the cooked index |
| |
| Copyright (C) 2022-2025 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 */ |