xref: /freebsd/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.h (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
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;
EntryEntry32     Entry(dw_tag_t t, const char *n) : tag(t), name(n) {}
33 
NameMatchesEntry34     bool NameMatches(const Entry &rhs) const {
35       if (name == rhs.name)
36         return true;
37       else if (name && rhs.name)
38         return strcmp(name, 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 
DWARFDeclContext()53   DWARFDeclContext() : m_entries() {}
54 
DWARFDeclContext(llvm::ArrayRef<Entry> entries)55   DWARFDeclContext(llvm::ArrayRef<Entry> entries) {
56     llvm::append_range(m_entries, entries);
57   }
58 
AppendDeclContext(dw_tag_t tag,const char * name)59   void AppendDeclContext(dw_tag_t tag, const char *name) {
60     m_entries.push_back(Entry(tag, name));
61   }
62 
63   bool operator==(const DWARFDeclContext &rhs) const;
64   bool operator!=(const DWARFDeclContext &rhs) const { return !(*this == rhs); }
65 
GetSize()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.
GetQualifiedNameAsConstString()82   ConstString GetQualifiedNameAsConstString() const {
83     return ConstString(GetQualifiedName());
84   }
85 
Clear()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(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