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 | |