| 1 | //===-- DWARFDeclContext.h --------------------------------------*- C++ -*-===// |
| 2 | // |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| 4 | // See https://llvm.org/LICENSE.txt for license information. |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| 6 | // |
| 7 | //===----------------------------------------------------------------------===// |
| 8 | |
| 9 | #ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDECLCONTEXT_H |
| 10 | #define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDECLCONTEXT_H |
| 11 | |
| 12 | #include "DWARFDefines.h" |
| 13 | #include "lldb/Utility/ConstString.h" |
| 14 | #include "llvm/ADT/StringExtras.h" |
| 15 | |
| 16 | #include <cassert> |
| 17 | #include <string> |
| 18 | #include <vector> |
| 19 | |
| 20 | namespace lldb_private::plugin { |
| 21 | namespace dwarf { |
| 22 | // DWARFDeclContext |
| 23 | // |
| 24 | // A class that represents a declaration context all the way down to a |
| 25 | // DIE. This is useful when trying to find a DIE in one DWARF to a DIE |
| 26 | // in another DWARF file. |
| 27 | |
| 28 | class DWARFDeclContext { |
| 29 | public: |
| 30 | struct Entry { |
| 31 | Entry() = default; |
| 32 | Entry(dw_tag_t t, const char *n) : tag(t), name(n) {} |
| 33 | |
| 34 | bool NameMatches(const Entry &rhs) const { |
| 35 | if (name == rhs.name) |
| 36 | return true; |
| 37 | else if (name && rhs.name) |
| 38 | return strcmp(s1: name, s2: rhs.name) == 0; |
| 39 | return false; |
| 40 | } |
| 41 | |
| 42 | /// Returns the name of this entry if it has one, or the appropriate |
| 43 | /// "anonymous {namespace, class, struct, union}". |
| 44 | const char *GetName() const; |
| 45 | |
| 46 | // Test operator |
| 47 | explicit operator bool() const { return tag != 0; } |
| 48 | |
| 49 | dw_tag_t tag = llvm::dwarf::DW_TAG_null; |
| 50 | const char *name = nullptr; |
| 51 | }; |
| 52 | |
| 53 | DWARFDeclContext() : m_entries() {} |
| 54 | |
| 55 | DWARFDeclContext(llvm::ArrayRef<Entry> entries) { |
| 56 | llvm::append_range(C&: m_entries, R&: entries); |
| 57 | } |
| 58 | |
| 59 | void AppendDeclContext(dw_tag_t tag, const char *name) { |
| 60 | m_entries.push_back(x: Entry(tag, name)); |
| 61 | } |
| 62 | |
| 63 | bool operator==(const DWARFDeclContext &rhs) const; |
| 64 | bool operator!=(const DWARFDeclContext &rhs) const { return !(*this == rhs); } |
| 65 | |
| 66 | uint32_t GetSize() const { return m_entries.size(); } |
| 67 | |
| 68 | Entry &operator[](uint32_t idx) { |
| 69 | assert(idx < m_entries.size() && "invalid index" ); |
| 70 | return m_entries[idx]; |
| 71 | } |
| 72 | |
| 73 | const Entry &operator[](uint32_t idx) const { |
| 74 | assert(idx < m_entries.size() && "invalid index" ); |
| 75 | return m_entries[idx]; |
| 76 | } |
| 77 | |
| 78 | const char *GetQualifiedName() const; |
| 79 | |
| 80 | // Same as GetQualifiedName, but the life time of the returned string will |
| 81 | // be that of the LLDB session. |
| 82 | ConstString GetQualifiedNameAsConstString() const { |
| 83 | return ConstString(GetQualifiedName()); |
| 84 | } |
| 85 | |
| 86 | void Clear() { |
| 87 | m_entries.clear(); |
| 88 | m_qualified_name.clear(); |
| 89 | } |
| 90 | |
| 91 | friend llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, |
| 92 | const DWARFDeclContext &ctx) { |
| 93 | OS << "DWARFDeclContext{" ; |
| 94 | llvm::ListSeparator LS; |
| 95 | for (const Entry &e : ctx.m_entries) { |
| 96 | OS << LS << "{" << DW_TAG_value_to_name(tag: e.tag) << ", " << e.GetName() |
| 97 | << "}" ; |
| 98 | } |
| 99 | return OS << "}" ; |
| 100 | } |
| 101 | |
| 102 | protected: |
| 103 | typedef std::vector<Entry> collection; |
| 104 | collection m_entries; |
| 105 | mutable std::string m_qualified_name; |
| 106 | }; |
| 107 | } // namespace dwarf |
| 108 | } // namespace lldb_private::plugin |
| 109 | |
| 110 | #endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDECLCONTEXT_H |
| 111 | |