LLDB mainline
ScriptedInstanceRegistry.cpp
Go to the documentation of this file.
1//===----------------------------------------------------------------------===//
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
10#include "lldb/Core/Debugger.h"
14#include "lldb/Utility/Stream.h"
15
16#include "llvm/ADT/StringMap.h"
17
18using namespace lldb;
19using namespace lldb_private;
20
21static bool HasArgs(const ScriptedInstanceInfo &info) {
22 return info.args_sp && info.args_sp->GetSize();
23}
24
25static bool CreatedBefore(const ScriptedInstanceInfo &lhs,
26 const ScriptedInstanceInfo &rhs) {
27 return lhs.id < rhs.id;
28}
29
31 std::lock_guard<std::mutex> guard(m_mutex);
32 const uint64_t id = m_next_id++;
33 info.id = id;
34 info.uuid = UUID::Generate();
35 m_instances[id] = std::move(info);
36 return id;
37}
38
40 std::lock_guard<std::mutex> guard(m_mutex);
41 m_instances.erase(id);
42}
43
44std::vector<ScriptedInstanceInfo>
46 std::lock_guard<std::mutex> guard(m_mutex);
47 std::vector<ScriptedInstanceInfo> instances;
48 instances.reserve(m_instances.size());
49 for (const auto &entry : m_instances)
50 instances.push_back(entry.second);
51 return instances;
52}
53
54std::vector<ScriptedInstanceInfo>
56 std::vector<ScriptedInstanceInfo> instances = CopyInstances();
57 llvm::sort(instances, CreatedBefore);
58 return instances;
59}
60
62 const ScriptedInstanceGroup &other) const {
63 if (class_name != other.class_name)
64 return class_name < other.class_name;
65
66 const std::string path = source_path.GetPath();
67 const std::string other_path = other.source_path.GetPath();
68 if (path != other_path)
69 return path < other_path;
70
71 return extension < other.extension;
72}
73
74std::vector<ScriptedInstanceGroup> ScriptedInstanceRegistry::GetInstanceGroups(
75 llvm::ArrayRef<ScriptedExtension> extensions) const {
76 // Unknown names map to eScriptedExtensionInvalid, the zero value.
77 llvm::StringMap<ScriptedExtension> extension_by_plugin;
78 for (size_t i = 0; i < PluginManager::GetNumScriptedInterfaces(); i++)
81
82 std::vector<ScriptedInstanceGroup> groups;
83 for (ScriptedInstanceInfo &info : CopyInstances()) {
84 ScriptedExtension extension = extension_by_plugin.lookup(info.plugin_name);
85 if (!extensions.empty() && !llvm::is_contained(extensions, extension))
86 continue;
87
88 auto it = llvm::find_if(groups, [&](const ScriptedInstanceGroup &group) {
89 return group.class_name == info.class_name &&
90 group.source_path == info.source_path &&
91 group.extension == extension;
92 });
93 if (it == groups.end()) {
94 it = groups.insert(groups.end(), ScriptedInstanceGroup());
95 it->class_name = info.class_name;
96 it->extension = extension;
97 it->source_path = info.source_path;
98 }
99 it->instances.push_back(std::move(info));
100 }
101
102 for (ScriptedInstanceGroup &group : groups)
103 llvm::sort(group.instances, CreatedBefore);
104 llvm::sort(groups);
105 return groups;
106}
107
109 auto group_sp = std::make_shared<StructuredData::Dictionary>();
110 group_sp->AddStringItem("class_name", class_name);
111 group_sp->AddStringItem("extension",
113 if (source_path)
114 group_sp->AddStringItem("source_path", source_path.GetPath());
115
116 auto instances_sp = std::make_shared<StructuredData::Array>();
117 for (const ScriptedInstanceInfo &info : instances) {
118 auto instance_sp = std::make_shared<StructuredData::Dictionary>();
119 instance_sp->AddStringItem("uuid", info.uuid.GetAsString());
120 if (info.object_address != LLDB_INVALID_ADDRESS)
121 instance_sp->AddIntegerItem("address", info.object_address);
122 if (HasArgs(info))
123 instance_sp->AddItem("args", info.args_sp);
124 instances_sp->AddItem(instance_sp);
125 }
126 group_sp->AddItem("instances", instances_sp);
127 return group_sp;
128}
129
131 bool use_color) const {
132 auto ansi_code = [use_color](llvm::StringRef code) {
133 return ansi::FormatAnsiTerminalCodes(code, use_color);
134 };
135 const std::string label_prefix = ansi_code(debugger.GetLabelAnsiPrefix());
136 const std::string label_suffix = ansi_code(debugger.GetLabelAnsiSuffix());
137 const std::string title_prefix = ansi_code(debugger.GetTitleAnsiPrefix());
138 const std::string title_suffix = ansi_code(debugger.GetTitleAnsiSuffix());
139
140 auto print_label = [&](llvm::StringRef indent, llvm::StringRef label) {
141 s << indent << label_prefix << label << ':' << label_suffix;
142 };
143 auto print_instance = [&](const ScriptedInstanceInfo &info) {
144 s << info.uuid.GetAsString();
145 if (info.object_address != LLDB_INVALID_ADDRESS)
146 s.Format(" ({0:x})", info.object_address);
147 s << '\n';
148 };
149 auto print_args = [&](const ScriptedInstanceInfo &info,
150 llvm::StringRef indent) {
151 if (!HasArgs(info))
152 return;
153 print_label(indent, "Args");
154 s << '\n';
155 info.args_sp->ForEachSorted(
156 [&](llvm::StringRef key, StructuredData::Object *value) {
157 s << indent << " - " << key << ": ";
158 if (StructuredData::String *str = value->GetAsString())
159 s << str->GetValue();
160 else
161 value->Dump(s, /*pretty_print=*/false);
162 s << '\n';
163 return true;
164 });
165 };
166
167 print_label(" ", "Class");
168 s << ' ' << title_prefix << class_name << title_suffix << '\n';
169 print_label(" ", "Extension");
171 if (source_path) {
172 print_label(" ", "Path");
173 s << ' ' << source_path.GetPath() << '\n';
174 }
175
176 if (instances.size() == 1) {
177 print_label(" ", "Instance");
178 s << ' ';
179 print_instance(instances.front());
180 print_args(instances.front(), " ");
181 return;
182 }
183
184 print_label(" ", "Instances");
185 s << '\n';
186 for (auto [idx, info] : llvm::enumerate(instances)) {
187 s.Format(" [{0}] ", idx);
188 print_instance(info);
189 print_args(info, " ");
190 }
191}
static bool HasArgs(const ScriptedInstanceInfo &info)
static bool CreatedBefore(const ScriptedInstanceInfo &lhs, const ScriptedInstanceInfo &rhs)
A class to manage flag bits.
Definition Debugger.h:101
llvm::StringRef GetLabelAnsiSuffix() const
Definition Debugger.cpp:587
llvm::StringRef GetTitleAnsiPrefix() const
Definition Debugger.cpp:593
llvm::StringRef GetTitleAnsiSuffix() const
Definition Debugger.cpp:599
llvm::StringRef GetLabelAnsiPrefix() const
Definition Debugger.cpp:581
size_t GetPath(char *path, size_t max_path_length, bool denormalize=true) const
Extract the full path to the file.
Definition FileSpec.cpp:380
static size_t GetNumScriptedInterfaces()
static lldb::ScriptedExtension GetScriptedInterfaceExtensionAtIndex(uint32_t idx)
static llvm::StringRef GetScriptedInterfaceNameAtIndex(uint32_t idx)
static llvm::StringLiteral ExtensionToString(lldb::ScriptedExtension extension)
std::vector< ScriptedInstanceInfo > CopyInstances() const
std::vector< ScriptedInstanceInfo > GetInstances() const
uint64_t Add(ScriptedInstanceInfo info)
std::vector< ScriptedInstanceGroup > GetInstanceGroups(llvm::ArrayRef< lldb::ScriptedExtension > extensions={}) const
llvm::DenseMap< uint64_t, ScriptedInstanceInfo > m_instances
A stream class that can stream formatted output to a file.
Definition Stream.h:28
void Format(const char *format, Args &&... args)
Forwards the arguments to llvm::formatv and writes to the stream.
Definition Stream.h:370
void Dump(lldb_private::Stream &s, bool pretty_print=true) const
std::shared_ptr< Dictionary > DictionarySP
static UUID Generate(uint32_t num_bytes=16)
Create a random UUID.
Definition UUID.cpp:119
#define LLDB_INVALID_ADDRESS
std::string FormatAnsiTerminalCodes(llvm::StringRef format, bool do_color=true)
A class that represents a running process on the host machine.
ScriptedExtension
Scripting extension types.
The live instances of one extension class.
bool operator<(const ScriptedInstanceGroup &other) const
void Dump(Stream &s, const Debugger &debugger, bool use_color) const
StructuredData::DictionarySP ToStructuredData() const
std::vector< ScriptedInstanceInfo > instances