Bug Summary

File:build/source/llvm/include/llvm/ADT/SmallBitVector.h
Warning:line 97, column 5
Use of memory after it is freed

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name PluginManager.cpp -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -ffunction-sections -fdata-sections -fcoverage-compilation-dir=/build/source/build-llvm/tools/clang/stage2-bins -resource-dir /usr/lib/llvm-17/lib/clang/17 -isystem /usr/include/libxml2 -D HAVE_ROUND -D _DEBUG -D _GLIBCXX_ASSERTIONS -D _GNU_SOURCE -D _LIBCPP_ENABLE_ASSERTIONS -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I tools/lldb/source/Core -I /build/source/lldb/source/Core -I /build/source/lldb/include -I tools/lldb/include -I include -I /build/source/llvm/include -I /usr/include/python3.9 -I /build/source/clang/include -I tools/lldb/../clang/include -I /build/source/lldb/source -I tools/lldb/source -D _FORTIFY_SOURCE=2 -D NDEBUG -U NDEBUG -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/x86_64-linux-gnu/c++/10 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/backward -internal-isystem /usr/lib/llvm-17/lib/clang/17/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -fmacro-prefix-map=/build/source/build-llvm/tools/clang/stage2-bins=build-llvm/tools/clang/stage2-bins -fmacro-prefix-map=/build/source/= -fcoverage-prefix-map=/build/source/build-llvm/tools/clang/stage2-bins=build-llvm/tools/clang/stage2-bins -fcoverage-prefix-map=/build/source/= -source-date-epoch 1683717183 -O2 -Wno-unused-command-line-argument -Wno-unused-parameter -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -Wno-maybe-uninitialized -Wno-class-memaccess -Wno-redundant-move -Wno-pessimizing-move -Wno-noexcept-type -Wno-comment -Wno-misleading-indentation -Wno-deprecated-declarations -Wno-unknown-pragmas -Wno-strict-aliasing -Wno-stringop-truncation -std=c++17 -fdeprecated-macro -fdebug-compilation-dir=/build/source/build-llvm/tools/clang/stage2-bins -fdebug-prefix-map=/build/source/build-llvm/tools/clang/stage2-bins=build-llvm/tools/clang/stage2-bins -fdebug-prefix-map=/build/source/= -ferror-limit 19 -fvisibility-inlines-hidden -stack-protector 2 -fgnuc-version=4.2.1 -fcolor-diagnostics -vectorize-loops -vectorize-slp -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/scan-build-2023-05-10-133810-16478-1 -x c++ /build/source/lldb/source/Core/PluginManager.cpp

/build/source/lldb/source/Core/PluginManager.cpp

1//===-- PluginManager.cpp -------------------------------------------------===//
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#include "lldb/Core/PluginManager.h"
10
11#include "lldb/Core/Debugger.h"
12#include "lldb/Host/FileSystem.h"
13#include "lldb/Host/HostInfo.h"
14#include "lldb/Interpreter/OptionValueProperties.h"
15#include "lldb/Target/Process.h"
16#include "lldb/Utility/ConstString.h"
17#include "lldb/Utility/FileSpec.h"
18#include "lldb/Utility/Status.h"
19#include "lldb/Utility/StringList.h"
20#include "llvm/ADT/StringRef.h"
21#include "llvm/Support/DynamicLibrary.h"
22#include "llvm/Support/FileSystem.h"
23#include "llvm/Support/raw_ostream.h"
24#include <cassert>
25#include <map>
26#include <memory>
27#include <mutex>
28#include <string>
29#include <utility>
30#include <vector>
31#if defined(_WIN32)
32#include "lldb/Host/windows/PosixApi.h"
33#endif
34
35using namespace lldb;
36using namespace lldb_private;
37
38typedef bool (*PluginInitCallback)();
39typedef void (*PluginTermCallback)();
40
41struct PluginInfo {
42 PluginInfo() = default;
43
44 llvm::sys::DynamicLibrary library;
45 PluginInitCallback plugin_init_callback = nullptr;
46 PluginTermCallback plugin_term_callback = nullptr;
47};
48
49typedef std::map<FileSpec, PluginInfo> PluginTerminateMap;
50
51static std::recursive_mutex &GetPluginMapMutex() {
52 static std::recursive_mutex g_plugin_map_mutex;
53 return g_plugin_map_mutex;
54}
55
56static PluginTerminateMap &GetPluginMap() {
57 static PluginTerminateMap g_plugin_map;
58 return g_plugin_map;
59}
60
61static bool PluginIsLoaded(const FileSpec &plugin_file_spec) {
62 std::lock_guard<std::recursive_mutex> guard(GetPluginMapMutex());
63 PluginTerminateMap &plugin_map = GetPluginMap();
64 return plugin_map.find(plugin_file_spec) != plugin_map.end();
65}
66
67static void SetPluginInfo(const FileSpec &plugin_file_spec,
68 const PluginInfo &plugin_info) {
69 std::lock_guard<std::recursive_mutex> guard(GetPluginMapMutex());
70 PluginTerminateMap &plugin_map = GetPluginMap();
71 assert(plugin_map.find(plugin_file_spec) == plugin_map.end())(static_cast <bool> (plugin_map.find(plugin_file_spec) ==
plugin_map.end()) ? void (0) : __assert_fail ("plugin_map.find(plugin_file_spec) == plugin_map.end()"
, "lldb/source/Core/PluginManager.cpp", 71, __extension__ __PRETTY_FUNCTION__
))
;
72 plugin_map[plugin_file_spec] = plugin_info;
73}
74
75template <typename FPtrTy> static FPtrTy CastToFPtr(void *VPtr) {
76 return reinterpret_cast<FPtrTy>(VPtr);
77}
78
79static FileSystem::EnumerateDirectoryResult
80LoadPluginCallback(void *baton, llvm::sys::fs::file_type ft,
81 llvm::StringRef path) {
82 Status error;
83
84 namespace fs = llvm::sys::fs;
85 // If we have a regular file, a symbolic link or unknown file type, try and
86 // process the file. We must handle unknown as sometimes the directory
87 // enumeration might be enumerating a file system that doesn't have correct
88 // file type information.
89 if (ft == fs::file_type::regular_file || ft == fs::file_type::symlink_file ||
90 ft == fs::file_type::type_unknown) {
91 FileSpec plugin_file_spec(path);
92 FileSystem::Instance().Resolve(plugin_file_spec);
93
94 if (PluginIsLoaded(plugin_file_spec))
95 return FileSystem::eEnumerateDirectoryResultNext;
96 else {
97 PluginInfo plugin_info;
98
99 std::string pluginLoadError;
100 plugin_info.library = llvm::sys::DynamicLibrary::getPermanentLibrary(
101 plugin_file_spec.GetPath().c_str(), &pluginLoadError);
102 if (plugin_info.library.isValid()) {
103 bool success = false;
104 plugin_info.plugin_init_callback = CastToFPtr<PluginInitCallback>(
105 plugin_info.library.getAddressOfSymbol("LLDBPluginInitialize"));
106 if (plugin_info.plugin_init_callback) {
107 // Call the plug-in "bool LLDBPluginInitialize(void)" function
108 success = plugin_info.plugin_init_callback();
109 }
110
111 if (success) {
112 // It is ok for the "LLDBPluginTerminate" symbol to be nullptr
113 plugin_info.plugin_term_callback = CastToFPtr<PluginTermCallback>(
114 plugin_info.library.getAddressOfSymbol("LLDBPluginTerminate"));
115 } else {
116 // The initialize function returned FALSE which means the plug-in
117 // might not be compatible, or might be too new or too old, or might
118 // not want to run on this machine. Set it to a default-constructed
119 // instance to invalidate it.
120 plugin_info = PluginInfo();
121 }
122
123 // Regardless of success or failure, cache the plug-in load in our
124 // plug-in info so we don't try to load it again and again.
125 SetPluginInfo(plugin_file_spec, plugin_info);
126
127 return FileSystem::eEnumerateDirectoryResultNext;
128 }
129 }
130 }
131
132 if (ft == fs::file_type::directory_file ||
133 ft == fs::file_type::symlink_file || ft == fs::file_type::type_unknown) {
134 // Try and recurse into anything that a directory or symbolic link. We must
135 // also do this for unknown as sometimes the directory enumeration might be
136 // enumerating a file system that doesn't have correct file type
137 // information.
138 return FileSystem::eEnumerateDirectoryResultEnter;
139 }
140
141 return FileSystem::eEnumerateDirectoryResultNext;
142}
143
144void PluginManager::Initialize() {
145 const bool find_directories = true;
146 const bool find_files = true;
147 const bool find_other = true;
148 char dir_path[PATH_MAX4096];
149 if (FileSpec dir_spec = HostInfo::GetSystemPluginDir()) {
150 if (FileSystem::Instance().Exists(dir_spec) &&
151 dir_spec.GetPath(dir_path, sizeof(dir_path))) {
152 FileSystem::Instance().EnumerateDirectory(dir_path, find_directories,
153 find_files, find_other,
154 LoadPluginCallback, nullptr);
155 }
156 }
157
158 if (FileSpec dir_spec = HostInfo::GetUserPluginDir()) {
159 if (FileSystem::Instance().Exists(dir_spec) &&
160 dir_spec.GetPath(dir_path, sizeof(dir_path))) {
161 FileSystem::Instance().EnumerateDirectory(dir_path, find_directories,
162 find_files, find_other,
163 LoadPluginCallback, nullptr);
164 }
165 }
166}
167
168void PluginManager::Terminate() {
169 std::lock_guard<std::recursive_mutex> guard(GetPluginMapMutex());
170 PluginTerminateMap &plugin_map = GetPluginMap();
171
172 PluginTerminateMap::const_iterator pos, end = plugin_map.end();
173 for (pos = plugin_map.begin(); pos != end; ++pos) {
174 // Call the plug-in "void LLDBPluginTerminate (void)" function if there is
175 // one (if the symbol was not nullptr).
176 if (pos->second.library.isValid()) {
177 if (pos->second.plugin_term_callback)
178 pos->second.plugin_term_callback();
179 }
180 }
181 plugin_map.clear();
182}
183
184template <typename Callback> struct PluginInstance {
185 typedef Callback CallbackType;
186
187 PluginInstance() = default;
188 PluginInstance(llvm::StringRef name, llvm::StringRef description,
189 Callback create_callback,
190 DebuggerInitializeCallback debugger_init_callback = nullptr)
191 : name(name), description(description), create_callback(create_callback),
192 debugger_init_callback(debugger_init_callback) {}
193
194 llvm::StringRef name;
195 llvm::StringRef description;
196 Callback create_callback;
197 DebuggerInitializeCallback debugger_init_callback;
198};
199
200template <typename Instance> class PluginInstances {
201public:
202 template <typename... Args>
203 bool RegisterPlugin(llvm::StringRef name, llvm::StringRef description,
204 typename Instance::CallbackType callback,
205 Args &&...args) {
206 if (!callback)
2
Assuming 'callback' is non-null
3
Taking false branch
207 return false;
208 assert(!name.empty())(static_cast <bool> (!name.empty()) ? void (0) : __assert_fail
("!name.empty()", "lldb/source/Core/PluginManager.cpp", 208,
__extension__ __PRETTY_FUNCTION__))
;
4
Assuming the condition is true
5
'?' condition is true
209 Instance instance =
210 Instance(name, description, callback, std::forward<Args>(args)...);
6
Calling implicit copy constructor for 'LanguageSet'
7
Calling copy constructor for 'SmallBitVector'
11
Returning from copy constructor for 'SmallBitVector'
12
Returning from copy constructor for 'LanguageSet'
13
Calling implicit destructor for 'LanguageSet'
14
Calling '~SmallBitVector'
18
Returning from '~SmallBitVector'
19
Returning from destructor for 'LanguageSet'
211 m_instances.push_back(instance);
212 return false;
20
Calling implicit destructor for 'TypeSystemInstance'
21
Calling implicit destructor for 'LanguageSet'
22
Calling '~SmallBitVector'
213 }
214
215 bool UnregisterPlugin(typename Instance::CallbackType callback) {
216 if (!callback)
217 return false;
218 auto pos = m_instances.begin();
219 auto end = m_instances.end();
220 for (; pos != end; ++pos) {
221 if (pos->create_callback == callback) {
222 m_instances.erase(pos);
223 return true;
224 }
225 }
226 return false;
227 }
228
229 typename Instance::CallbackType GetCallbackAtIndex(uint32_t idx) {
230 if (Instance *instance = GetInstanceAtIndex(idx))
231 return instance->create_callback;
232 return nullptr;
233 }
234
235 llvm::StringRef GetDescriptionAtIndex(uint32_t idx) {
236 if (Instance *instance = GetInstanceAtIndex(idx))
237 return instance->description;
238 return "";
239 }
240
241 llvm::StringRef GetNameAtIndex(uint32_t idx) {
242 if (Instance *instance = GetInstanceAtIndex(idx))
243 return instance->name;
244 return "";
245 }
246
247 typename Instance::CallbackType GetCallbackForName(llvm::StringRef name) {
248 if (name.empty())
249 return nullptr;
250 for (auto &instance : m_instances) {
251 if (name == instance.name)
252 return instance.create_callback;
253 }
254 return nullptr;
255 }
256
257 void PerformDebuggerCallback(Debugger &debugger) {
258 for (auto &instance : m_instances) {
259 if (instance.debugger_init_callback)
260 instance.debugger_init_callback(debugger);
261 }
262 }
263
264 const std::vector<Instance> &GetInstances() const { return m_instances; }
265 std::vector<Instance> &GetInstances() { return m_instances; }
266
267 Instance *GetInstanceAtIndex(uint32_t idx) {
268 if (idx < m_instances.size())
269 return &m_instances[idx];
270 return nullptr;
271 }
272
273private:
274 std::vector<Instance> m_instances;
275};
276
277#pragma mark ABI
278
279typedef PluginInstance<ABICreateInstance> ABIInstance;
280typedef PluginInstances<ABIInstance> ABIInstances;
281
282static ABIInstances &GetABIInstances() {
283 static ABIInstances g_instances;
284 return g_instances;
285}
286
287bool PluginManager::RegisterPlugin(llvm::StringRef name,
288 llvm::StringRef description,
289 ABICreateInstance create_callback) {
290 return GetABIInstances().RegisterPlugin(name, description, create_callback);
291}
292
293bool PluginManager::UnregisterPlugin(ABICreateInstance create_callback) {
294 return GetABIInstances().UnregisterPlugin(create_callback);
295}
296
297ABICreateInstance PluginManager::GetABICreateCallbackAtIndex(uint32_t idx) {
298 return GetABIInstances().GetCallbackAtIndex(idx);
299}
300
301#pragma mark Architecture
302
303typedef PluginInstance<ArchitectureCreateInstance> ArchitectureInstance;
304typedef std::vector<ArchitectureInstance> ArchitectureInstances;
305
306static ArchitectureInstances &GetArchitectureInstances() {
307 static ArchitectureInstances g_instances;
308 return g_instances;
309}
310
311void PluginManager::RegisterPlugin(llvm::StringRef name,
312 llvm::StringRef description,
313 ArchitectureCreateInstance create_callback) {
314 GetArchitectureInstances().push_back({name, description, create_callback});
315}
316
317void PluginManager::UnregisterPlugin(
318 ArchitectureCreateInstance create_callback) {
319 auto &instances = GetArchitectureInstances();
320
321 for (auto pos = instances.begin(), end = instances.end(); pos != end; ++pos) {
322 if (pos->create_callback == create_callback) {
323 instances.erase(pos);
324 return;
325 }
326 }
327 llvm_unreachable("Plugin not found")::llvm::llvm_unreachable_internal("Plugin not found", "lldb/source/Core/PluginManager.cpp"
, 327)
;
328}
329
330std::unique_ptr<Architecture>
331PluginManager::CreateArchitectureInstance(const ArchSpec &arch) {
332 for (const auto &instances : GetArchitectureInstances()) {
333 if (auto plugin_up = instances.create_callback(arch))
334 return plugin_up;
335 }
336 return nullptr;
337}
338
339#pragma mark Disassembler
340
341typedef PluginInstance<DisassemblerCreateInstance> DisassemblerInstance;
342typedef PluginInstances<DisassemblerInstance> DisassemblerInstances;
343
344static DisassemblerInstances &GetDisassemblerInstances() {
345 static DisassemblerInstances g_instances;
346 return g_instances;
347}
348
349bool PluginManager::RegisterPlugin(llvm::StringRef name,
350 llvm::StringRef description,
351 DisassemblerCreateInstance create_callback) {
352 return GetDisassemblerInstances().RegisterPlugin(name, description,
353 create_callback);
354}
355
356bool PluginManager::UnregisterPlugin(
357 DisassemblerCreateInstance create_callback) {
358 return GetDisassemblerInstances().UnregisterPlugin(create_callback);
359}
360
361DisassemblerCreateInstance
362PluginManager::GetDisassemblerCreateCallbackAtIndex(uint32_t idx) {
363 return GetDisassemblerInstances().GetCallbackAtIndex(idx);
364}
365
366DisassemblerCreateInstance
367PluginManager::GetDisassemblerCreateCallbackForPluginName(
368 llvm::StringRef name) {
369 return GetDisassemblerInstances().GetCallbackForName(name);
370}
371
372#pragma mark DynamicLoader
373
374typedef PluginInstance<DynamicLoaderCreateInstance> DynamicLoaderInstance;
375typedef PluginInstances<DynamicLoaderInstance> DynamicLoaderInstances;
376
377static DynamicLoaderInstances &GetDynamicLoaderInstances() {
378 static DynamicLoaderInstances g_instances;
379 return g_instances;
380}
381
382bool PluginManager::RegisterPlugin(
383 llvm::StringRef name, llvm::StringRef description,
384 DynamicLoaderCreateInstance create_callback,
385 DebuggerInitializeCallback debugger_init_callback) {
386 return GetDynamicLoaderInstances().RegisterPlugin(
387 name, description, create_callback, debugger_init_callback);
388}
389
390bool PluginManager::UnregisterPlugin(
391 DynamicLoaderCreateInstance create_callback) {
392 return GetDynamicLoaderInstances().UnregisterPlugin(create_callback);
393}
394
395DynamicLoaderCreateInstance
396PluginManager::GetDynamicLoaderCreateCallbackAtIndex(uint32_t idx) {
397 return GetDynamicLoaderInstances().GetCallbackAtIndex(idx);
398}
399
400DynamicLoaderCreateInstance
401PluginManager::GetDynamicLoaderCreateCallbackForPluginName(
402 llvm::StringRef name) {
403 return GetDynamicLoaderInstances().GetCallbackForName(name);
404}
405
406#pragma mark JITLoader
407
408typedef PluginInstance<JITLoaderCreateInstance> JITLoaderInstance;
409typedef PluginInstances<JITLoaderInstance> JITLoaderInstances;
410
411static JITLoaderInstances &GetJITLoaderInstances() {
412 static JITLoaderInstances g_instances;
413 return g_instances;
414}
415
416bool PluginManager::RegisterPlugin(
417 llvm::StringRef name, llvm::StringRef description,
418 JITLoaderCreateInstance create_callback,
419 DebuggerInitializeCallback debugger_init_callback) {
420 return GetJITLoaderInstances().RegisterPlugin(
421 name, description, create_callback, debugger_init_callback);
422}
423
424bool PluginManager::UnregisterPlugin(JITLoaderCreateInstance create_callback) {
425 return GetJITLoaderInstances().UnregisterPlugin(create_callback);
426}
427
428JITLoaderCreateInstance
429PluginManager::GetJITLoaderCreateCallbackAtIndex(uint32_t idx) {
430 return GetJITLoaderInstances().GetCallbackAtIndex(idx);
431}
432
433#pragma mark EmulateInstruction
434
435typedef PluginInstance<EmulateInstructionCreateInstance>
436 EmulateInstructionInstance;
437typedef PluginInstances<EmulateInstructionInstance> EmulateInstructionInstances;
438
439static EmulateInstructionInstances &GetEmulateInstructionInstances() {
440 static EmulateInstructionInstances g_instances;
441 return g_instances;
442}
443
444bool PluginManager::RegisterPlugin(
445 llvm::StringRef name, llvm::StringRef description,
446 EmulateInstructionCreateInstance create_callback) {
447 return GetEmulateInstructionInstances().RegisterPlugin(name, description,
448 create_callback);
449}
450
451bool PluginManager::UnregisterPlugin(
452 EmulateInstructionCreateInstance create_callback) {
453 return GetEmulateInstructionInstances().UnregisterPlugin(create_callback);
454}
455
456EmulateInstructionCreateInstance
457PluginManager::GetEmulateInstructionCreateCallbackAtIndex(uint32_t idx) {
458 return GetEmulateInstructionInstances().GetCallbackAtIndex(idx);
459}
460
461EmulateInstructionCreateInstance
462PluginManager::GetEmulateInstructionCreateCallbackForPluginName(
463 llvm::StringRef name) {
464 return GetEmulateInstructionInstances().GetCallbackForName(name);
465}
466
467#pragma mark OperatingSystem
468
469typedef PluginInstance<OperatingSystemCreateInstance> OperatingSystemInstance;
470typedef PluginInstances<OperatingSystemInstance> OperatingSystemInstances;
471
472static OperatingSystemInstances &GetOperatingSystemInstances() {
473 static OperatingSystemInstances g_instances;
474 return g_instances;
475}
476
477bool PluginManager::RegisterPlugin(
478 llvm::StringRef name, llvm::StringRef description,
479 OperatingSystemCreateInstance create_callback,
480 DebuggerInitializeCallback debugger_init_callback) {
481 return GetOperatingSystemInstances().RegisterPlugin(
482 name, description, create_callback, debugger_init_callback);
483}
484
485bool PluginManager::UnregisterPlugin(
486 OperatingSystemCreateInstance create_callback) {
487 return GetOperatingSystemInstances().UnregisterPlugin(create_callback);
488}
489
490OperatingSystemCreateInstance
491PluginManager::GetOperatingSystemCreateCallbackAtIndex(uint32_t idx) {
492 return GetOperatingSystemInstances().GetCallbackAtIndex(idx);
493}
494
495OperatingSystemCreateInstance
496PluginManager::GetOperatingSystemCreateCallbackForPluginName(
497 llvm::StringRef name) {
498 return GetOperatingSystemInstances().GetCallbackForName(name);
499}
500
501#pragma mark Language
502
503typedef PluginInstance<LanguageCreateInstance> LanguageInstance;
504typedef PluginInstances<LanguageInstance> LanguageInstances;
505
506static LanguageInstances &GetLanguageInstances() {
507 static LanguageInstances g_instances;
508 return g_instances;
509}
510
511bool PluginManager::RegisterPlugin(llvm::StringRef name,
512 llvm::StringRef description,
513 LanguageCreateInstance create_callback) {
514 return GetLanguageInstances().RegisterPlugin(name, description,
515 create_callback);
516}
517
518bool PluginManager::UnregisterPlugin(LanguageCreateInstance create_callback) {
519 return GetLanguageInstances().UnregisterPlugin(create_callback);
520}
521
522LanguageCreateInstance
523PluginManager::GetLanguageCreateCallbackAtIndex(uint32_t idx) {
524 return GetLanguageInstances().GetCallbackAtIndex(idx);
525}
526
527#pragma mark LanguageRuntime
528
529struct LanguageRuntimeInstance
530 : public PluginInstance<LanguageRuntimeCreateInstance> {
531 LanguageRuntimeInstance(
532 llvm::StringRef name, llvm::StringRef description,
533 CallbackType create_callback,
534 DebuggerInitializeCallback debugger_init_callback,
535 LanguageRuntimeGetCommandObject command_callback,
536 LanguageRuntimeGetExceptionPrecondition precondition_callback)
537 : PluginInstance<LanguageRuntimeCreateInstance>(
538 name, description, create_callback, debugger_init_callback),
539 command_callback(command_callback),
540 precondition_callback(precondition_callback) {}
541
542 LanguageRuntimeGetCommandObject command_callback;
543 LanguageRuntimeGetExceptionPrecondition precondition_callback;
544};
545
546typedef PluginInstances<LanguageRuntimeInstance> LanguageRuntimeInstances;
547
548static LanguageRuntimeInstances &GetLanguageRuntimeInstances() {
549 static LanguageRuntimeInstances g_instances;
550 return g_instances;
551}
552
553bool PluginManager::RegisterPlugin(
554 llvm::StringRef name, llvm::StringRef description,
555 LanguageRuntimeCreateInstance create_callback,
556 LanguageRuntimeGetCommandObject command_callback,
557 LanguageRuntimeGetExceptionPrecondition precondition_callback) {
558 return GetLanguageRuntimeInstances().RegisterPlugin(
559 name, description, create_callback, nullptr, command_callback,
560 precondition_callback);
561}
562
563bool PluginManager::UnregisterPlugin(
564 LanguageRuntimeCreateInstance create_callback) {
565 return GetLanguageRuntimeInstances().UnregisterPlugin(create_callback);
566}
567
568LanguageRuntimeCreateInstance
569PluginManager::GetLanguageRuntimeCreateCallbackAtIndex(uint32_t idx) {
570 return GetLanguageRuntimeInstances().GetCallbackAtIndex(idx);
571}
572
573LanguageRuntimeGetCommandObject
574PluginManager::GetLanguageRuntimeGetCommandObjectAtIndex(uint32_t idx) {
575 const auto &instances = GetLanguageRuntimeInstances().GetInstances();
576 if (idx < instances.size())
577 return instances[idx].command_callback;
578 return nullptr;
579}
580
581LanguageRuntimeGetExceptionPrecondition
582PluginManager::GetLanguageRuntimeGetExceptionPreconditionAtIndex(uint32_t idx) {
583 const auto &instances = GetLanguageRuntimeInstances().GetInstances();
584 if (idx < instances.size())
585 return instances[idx].precondition_callback;
586 return nullptr;
587}
588
589#pragma mark SystemRuntime
590
591typedef PluginInstance<SystemRuntimeCreateInstance> SystemRuntimeInstance;
592typedef PluginInstances<SystemRuntimeInstance> SystemRuntimeInstances;
593
594static SystemRuntimeInstances &GetSystemRuntimeInstances() {
595 static SystemRuntimeInstances g_instances;
596 return g_instances;
597}
598
599bool PluginManager::RegisterPlugin(
600 llvm::StringRef name, llvm::StringRef description,
601 SystemRuntimeCreateInstance create_callback) {
602 return GetSystemRuntimeInstances().RegisterPlugin(name, description,
603 create_callback);
604}
605
606bool PluginManager::UnregisterPlugin(
607 SystemRuntimeCreateInstance create_callback) {
608 return GetSystemRuntimeInstances().UnregisterPlugin(create_callback);
609}
610
611SystemRuntimeCreateInstance
612PluginManager::GetSystemRuntimeCreateCallbackAtIndex(uint32_t idx) {
613 return GetSystemRuntimeInstances().GetCallbackAtIndex(idx);
614}
615
616#pragma mark ObjectFile
617
618struct ObjectFileInstance : public PluginInstance<ObjectFileCreateInstance> {
619 ObjectFileInstance(
620 llvm::StringRef name, llvm::StringRef description,
621 CallbackType create_callback,
622 ObjectFileCreateMemoryInstance create_memory_callback,
623 ObjectFileGetModuleSpecifications get_module_specifications,
624 ObjectFileSaveCore save_core,
625 DebuggerInitializeCallback debugger_init_callback)
626 : PluginInstance<ObjectFileCreateInstance>(
627 name, description, create_callback, debugger_init_callback),
628 create_memory_callback(create_memory_callback),
629 get_module_specifications(get_module_specifications),
630 save_core(save_core) {}
631
632 ObjectFileCreateMemoryInstance create_memory_callback;
633 ObjectFileGetModuleSpecifications get_module_specifications;
634 ObjectFileSaveCore save_core;
635};
636typedef PluginInstances<ObjectFileInstance> ObjectFileInstances;
637
638static ObjectFileInstances &GetObjectFileInstances() {
639 static ObjectFileInstances g_instances;
640 return g_instances;
641}
642
643bool PluginManager::RegisterPlugin(
644 llvm::StringRef name, llvm::StringRef description,
645 ObjectFileCreateInstance create_callback,
646 ObjectFileCreateMemoryInstance create_memory_callback,
647 ObjectFileGetModuleSpecifications get_module_specifications,
648 ObjectFileSaveCore save_core,
649 DebuggerInitializeCallback debugger_init_callback) {
650 return GetObjectFileInstances().RegisterPlugin(
651 name, description, create_callback, create_memory_callback,
652 get_module_specifications, save_core, debugger_init_callback);
653}
654
655bool PluginManager::UnregisterPlugin(ObjectFileCreateInstance create_callback) {
656 return GetObjectFileInstances().UnregisterPlugin(create_callback);
657}
658
659ObjectFileCreateInstance
660PluginManager::GetObjectFileCreateCallbackAtIndex(uint32_t idx) {
661 return GetObjectFileInstances().GetCallbackAtIndex(idx);
662}
663
664ObjectFileCreateMemoryInstance
665PluginManager::GetObjectFileCreateMemoryCallbackAtIndex(uint32_t idx) {
666 const auto &instances = GetObjectFileInstances().GetInstances();
667 if (idx < instances.size())
668 return instances[idx].create_memory_callback;
669 return nullptr;
670}
671
672ObjectFileGetModuleSpecifications
673PluginManager::GetObjectFileGetModuleSpecificationsCallbackAtIndex(
674 uint32_t idx) {
675 const auto &instances = GetObjectFileInstances().GetInstances();
676 if (idx < instances.size())
677 return instances[idx].get_module_specifications;
678 return nullptr;
679}
680
681ObjectFileCreateMemoryInstance
682PluginManager::GetObjectFileCreateMemoryCallbackForPluginName(
683 llvm::StringRef name) {
684 const auto &instances = GetObjectFileInstances().GetInstances();
685 for (auto &instance : instances) {
686 if (instance.name == name)
687 return instance.create_memory_callback;
688 }
689 return nullptr;
690}
691
692Status PluginManager::SaveCore(const lldb::ProcessSP &process_sp,
693 const FileSpec &outfile,
694 lldb::SaveCoreStyle &core_style,
695 llvm::StringRef plugin_name) {
696 if (plugin_name.empty()) {
697 // Try saving core directly from the process plugin first.
698 llvm::Expected<bool> ret = process_sp->SaveCore(outfile.GetPath());
699 if (!ret)
700 return Status(ret.takeError());
701 if (ret.get())
702 return Status();
703 }
704
705 // Fall back to object plugins.
706 Status error;
707 auto &instances = GetObjectFileInstances().GetInstances();
708 for (auto &instance : instances) {
709 if (plugin_name.empty() || instance.name == plugin_name) {
710 if (instance.save_core &&
711 instance.save_core(process_sp, outfile, core_style, error))
712 return error;
713 }
714 }
715 error.SetErrorString(
716 "no ObjectFile plugins were able to save a core for this process");
717 return error;
718}
719
720#pragma mark ObjectContainer
721
722struct ObjectContainerInstance
723 : public PluginInstance<ObjectContainerCreateInstance> {
724 ObjectContainerInstance(
725 llvm::StringRef name, llvm::StringRef description,
726 CallbackType create_callback,
727 ObjectContainerCreateMemoryInstance create_memory_callback,
728 ObjectFileGetModuleSpecifications get_module_specifications)
729 : PluginInstance<ObjectContainerCreateInstance>(name, description,
730 create_callback),
731 create_memory_callback(create_memory_callback),
732 get_module_specifications(get_module_specifications) {}
733
734 ObjectContainerCreateMemoryInstance create_memory_callback;
735 ObjectFileGetModuleSpecifications get_module_specifications;
736};
737typedef PluginInstances<ObjectContainerInstance> ObjectContainerInstances;
738
739static ObjectContainerInstances &GetObjectContainerInstances() {
740 static ObjectContainerInstances g_instances;
741 return g_instances;
742}
743
744bool PluginManager::RegisterPlugin(
745 llvm::StringRef name, llvm::StringRef description,
746 ObjectContainerCreateInstance create_callback,
747 ObjectFileGetModuleSpecifications get_module_specifications,
748 ObjectContainerCreateMemoryInstance create_memory_callback) {
749 return GetObjectContainerInstances().RegisterPlugin(
750 name, description, create_callback, create_memory_callback,
751 get_module_specifications);
752}
753
754bool PluginManager::UnregisterPlugin(
755 ObjectContainerCreateInstance create_callback) {
756 return GetObjectContainerInstances().UnregisterPlugin(create_callback);
757}
758
759ObjectContainerCreateInstance
760PluginManager::GetObjectContainerCreateCallbackAtIndex(uint32_t idx) {
761 return GetObjectContainerInstances().GetCallbackAtIndex(idx);
762}
763
764ObjectContainerCreateMemoryInstance
765PluginManager::GetObjectContainerCreateMemoryCallbackAtIndex(uint32_t idx) {
766 const auto &instances = GetObjectContainerInstances().GetInstances();
767 if (idx < instances.size())
768 return instances[idx].create_memory_callback;
769 return nullptr;
770}
771
772ObjectFileGetModuleSpecifications
773PluginManager::GetObjectContainerGetModuleSpecificationsCallbackAtIndex(
774 uint32_t idx) {
775 const auto &instances = GetObjectContainerInstances().GetInstances();
776 if (idx < instances.size())
777 return instances[idx].get_module_specifications;
778 return nullptr;
779}
780
781#pragma mark Platform
782
783typedef PluginInstance<PlatformCreateInstance> PlatformInstance;
784typedef PluginInstances<PlatformInstance> PlatformInstances;
785
786static PlatformInstances &GetPlatformInstances() {
787 static PlatformInstances g_platform_instances;
788 return g_platform_instances;
789}
790
791bool PluginManager::RegisterPlugin(
792 llvm::StringRef name, llvm::StringRef description,
793 PlatformCreateInstance create_callback,
794 DebuggerInitializeCallback debugger_init_callback) {
795 return GetPlatformInstances().RegisterPlugin(
796 name, description, create_callback, debugger_init_callback);
797}
798
799bool PluginManager::UnregisterPlugin(PlatformCreateInstance create_callback) {
800 return GetPlatformInstances().UnregisterPlugin(create_callback);
801}
802
803llvm::StringRef PluginManager::GetPlatformPluginNameAtIndex(uint32_t idx) {
804 return GetPlatformInstances().GetNameAtIndex(idx);
805}
806
807llvm::StringRef
808PluginManager::GetPlatformPluginDescriptionAtIndex(uint32_t idx) {
809 return GetPlatformInstances().GetDescriptionAtIndex(idx);
810}
811
812PlatformCreateInstance
813PluginManager::GetPlatformCreateCallbackAtIndex(uint32_t idx) {
814 return GetPlatformInstances().GetCallbackAtIndex(idx);
815}
816
817PlatformCreateInstance
818PluginManager::GetPlatformCreateCallbackForPluginName(llvm::StringRef name) {
819 return GetPlatformInstances().GetCallbackForName(name);
820}
821
822void PluginManager::AutoCompletePlatformName(llvm::StringRef name,
823 CompletionRequest &request) {
824 for (const auto &instance : GetPlatformInstances().GetInstances()) {
825 if (instance.name.startswith(name))
826 request.AddCompletion(instance.name);
827 }
828}
829
830#pragma mark Process
831
832typedef PluginInstance<ProcessCreateInstance> ProcessInstance;
833typedef PluginInstances<ProcessInstance> ProcessInstances;
834
835static ProcessInstances &GetProcessInstances() {
836 static ProcessInstances g_instances;
837 return g_instances;
838}
839
840bool PluginManager::RegisterPlugin(
841 llvm::StringRef name, llvm::StringRef description,
842 ProcessCreateInstance create_callback,
843 DebuggerInitializeCallback debugger_init_callback) {
844 return GetProcessInstances().RegisterPlugin(
845 name, description, create_callback, debugger_init_callback);
846}
847
848bool PluginManager::UnregisterPlugin(ProcessCreateInstance create_callback) {
849 return GetProcessInstances().UnregisterPlugin(create_callback);
850}
851
852llvm::StringRef PluginManager::GetProcessPluginNameAtIndex(uint32_t idx) {
853 return GetProcessInstances().GetNameAtIndex(idx);
854}
855
856llvm::StringRef PluginManager::GetProcessPluginDescriptionAtIndex(uint32_t idx) {
857 return GetProcessInstances().GetDescriptionAtIndex(idx);
858}
859
860ProcessCreateInstance
861PluginManager::GetProcessCreateCallbackAtIndex(uint32_t idx) {
862 return GetProcessInstances().GetCallbackAtIndex(idx);
863}
864
865ProcessCreateInstance
866PluginManager::GetProcessCreateCallbackForPluginName(llvm::StringRef name) {
867 return GetProcessInstances().GetCallbackForName(name);
868}
869
870void PluginManager::AutoCompleteProcessName(llvm::StringRef name,
871 CompletionRequest &request) {
872 for (const auto &instance : GetProcessInstances().GetInstances()) {
873 if (instance.name.startswith(name))
874 request.AddCompletion(instance.name, instance.description);
875 }
876}
877
878#pragma mark RegisterTypeBuilder
879
880struct RegisterTypeBuilderInstance
881 : public PluginInstance<RegisterTypeBuilderCreateInstance> {
882 RegisterTypeBuilderInstance(llvm::StringRef name, llvm::StringRef description,
883 CallbackType create_callback)
884 : PluginInstance<RegisterTypeBuilderCreateInstance>(name, description,
885 create_callback) {}
886};
887
888typedef PluginInstances<RegisterTypeBuilderInstance>
889 RegisterTypeBuilderInstances;
890
891static RegisterTypeBuilderInstances &GetRegisterTypeBuilderInstances() {
892 static RegisterTypeBuilderInstances g_instances;
893 return g_instances;
894}
895
896bool PluginManager::RegisterPlugin(
897 llvm::StringRef name, llvm::StringRef description,
898 RegisterTypeBuilderCreateInstance create_callback) {
899 return GetRegisterTypeBuilderInstances().RegisterPlugin(name, description,
900 create_callback);
901}
902
903bool PluginManager::UnregisterPlugin(
904 RegisterTypeBuilderCreateInstance create_callback) {
905 return GetRegisterTypeBuilderInstances().UnregisterPlugin(create_callback);
906}
907
908lldb::RegisterTypeBuilderSP
909PluginManager::GetRegisterTypeBuilder(Target &target) {
910 const auto &instances = GetRegisterTypeBuilderInstances().GetInstances();
911 // We assume that RegisterTypeBuilderClang is the only instance of this plugin
912 // type and is always present.
913 assert(instances.size())(static_cast <bool> (instances.size()) ? void (0) : __assert_fail
("instances.size()", "lldb/source/Core/PluginManager.cpp", 913
, __extension__ __PRETTY_FUNCTION__))
;
914 return instances[0].create_callback(target);
915}
916
917#pragma mark ScriptInterpreter
918
919struct ScriptInterpreterInstance
920 : public PluginInstance<ScriptInterpreterCreateInstance> {
921 ScriptInterpreterInstance(llvm::StringRef name, llvm::StringRef description,
922 CallbackType create_callback,
923 lldb::ScriptLanguage language)
924 : PluginInstance<ScriptInterpreterCreateInstance>(name, description,
925 create_callback),
926 language(language) {}
927
928 lldb::ScriptLanguage language = lldb::eScriptLanguageNone;
929};
930
931typedef PluginInstances<ScriptInterpreterInstance> ScriptInterpreterInstances;
932
933static ScriptInterpreterInstances &GetScriptInterpreterInstances() {
934 static ScriptInterpreterInstances g_instances;
935 return g_instances;
936}
937
938bool PluginManager::RegisterPlugin(
939 llvm::StringRef name, llvm::StringRef description,
940 lldb::ScriptLanguage script_language,
941 ScriptInterpreterCreateInstance create_callback) {
942 return GetScriptInterpreterInstances().RegisterPlugin(
943 name, description, create_callback, script_language);
944}
945
946bool PluginManager::UnregisterPlugin(
947 ScriptInterpreterCreateInstance create_callback) {
948 return GetScriptInterpreterInstances().UnregisterPlugin(create_callback);
949}
950
951ScriptInterpreterCreateInstance
952PluginManager::GetScriptInterpreterCreateCallbackAtIndex(uint32_t idx) {
953 return GetScriptInterpreterInstances().GetCallbackAtIndex(idx);
954}
955
956lldb::ScriptInterpreterSP
957PluginManager::GetScriptInterpreterForLanguage(lldb::ScriptLanguage script_lang,
958 Debugger &debugger) {
959 const auto &instances = GetScriptInterpreterInstances().GetInstances();
960 ScriptInterpreterCreateInstance none_instance = nullptr;
961 for (const auto &instance : instances) {
962 if (instance.language == lldb::eScriptLanguageNone)
963 none_instance = instance.create_callback;
964
965 if (script_lang == instance.language)
966 return instance.create_callback(debugger);
967 }
968
969 // If we didn't find one, return the ScriptInterpreter for the null language.
970 assert(none_instance != nullptr)(static_cast <bool> (none_instance != nullptr) ? void (
0) : __assert_fail ("none_instance != nullptr", "lldb/source/Core/PluginManager.cpp"
, 970, __extension__ __PRETTY_FUNCTION__))
;
971 return none_instance(debugger);
972}
973
974#pragma mark StructuredDataPlugin
975
976struct StructuredDataPluginInstance
977 : public PluginInstance<StructuredDataPluginCreateInstance> {
978 StructuredDataPluginInstance(
979 llvm::StringRef name, llvm::StringRef description,
980 CallbackType create_callback,
981 DebuggerInitializeCallback debugger_init_callback,
982 StructuredDataFilterLaunchInfo filter_callback)
983 : PluginInstance<StructuredDataPluginCreateInstance>(
984 name, description, create_callback, debugger_init_callback),
985 filter_callback(filter_callback) {}
986
987 StructuredDataFilterLaunchInfo filter_callback = nullptr;
988};
989
990typedef PluginInstances<StructuredDataPluginInstance>
991 StructuredDataPluginInstances;
992
993static StructuredDataPluginInstances &GetStructuredDataPluginInstances() {
994 static StructuredDataPluginInstances g_instances;
995 return g_instances;
996}
997
998bool PluginManager::RegisterPlugin(
999 llvm::StringRef name, llvm::StringRef description,
1000 StructuredDataPluginCreateInstance create_callback,
1001 DebuggerInitializeCallback debugger_init_callback,
1002 StructuredDataFilterLaunchInfo filter_callback) {
1003 return GetStructuredDataPluginInstances().RegisterPlugin(
1004 name, description, create_callback, debugger_init_callback,
1005 filter_callback);
1006}
1007
1008bool PluginManager::UnregisterPlugin(
1009 StructuredDataPluginCreateInstance create_callback) {
1010 return GetStructuredDataPluginInstances().UnregisterPlugin(create_callback);
1011}
1012
1013StructuredDataPluginCreateInstance
1014PluginManager::GetStructuredDataPluginCreateCallbackAtIndex(uint32_t idx) {
1015 return GetStructuredDataPluginInstances().GetCallbackAtIndex(idx);
1016}
1017
1018StructuredDataFilterLaunchInfo
1019PluginManager::GetStructuredDataFilterCallbackAtIndex(
1020 uint32_t idx, bool &iteration_complete) {
1021 const auto &instances = GetStructuredDataPluginInstances().GetInstances();
1022 if (idx < instances.size()) {
1023 iteration_complete = false;
1024 return instances[idx].filter_callback;
1025 } else {
1026 iteration_complete = true;
1027 }
1028 return nullptr;
1029}
1030
1031#pragma mark SymbolFile
1032
1033typedef PluginInstance<SymbolFileCreateInstance> SymbolFileInstance;
1034typedef PluginInstances<SymbolFileInstance> SymbolFileInstances;
1035
1036static SymbolFileInstances &GetSymbolFileInstances() {
1037 static SymbolFileInstances g_instances;
1038 return g_instances;
1039}
1040
1041bool PluginManager::RegisterPlugin(
1042 llvm::StringRef name, llvm::StringRef description,
1043 SymbolFileCreateInstance create_callback,
1044 DebuggerInitializeCallback debugger_init_callback) {
1045 return GetSymbolFileInstances().RegisterPlugin(
1046 name, description, create_callback, debugger_init_callback);
1047}
1048
1049bool PluginManager::UnregisterPlugin(SymbolFileCreateInstance create_callback) {
1050 return GetSymbolFileInstances().UnregisterPlugin(create_callback);
1051}
1052
1053SymbolFileCreateInstance
1054PluginManager::GetSymbolFileCreateCallbackAtIndex(uint32_t idx) {
1055 return GetSymbolFileInstances().GetCallbackAtIndex(idx);
1056}
1057
1058#pragma mark SymbolVendor
1059
1060typedef PluginInstance<SymbolVendorCreateInstance> SymbolVendorInstance;
1061typedef PluginInstances<SymbolVendorInstance> SymbolVendorInstances;
1062
1063static SymbolVendorInstances &GetSymbolVendorInstances() {
1064 static SymbolVendorInstances g_instances;
1065 return g_instances;
1066}
1067
1068bool PluginManager::RegisterPlugin(llvm::StringRef name,
1069 llvm::StringRef description,
1070 SymbolVendorCreateInstance create_callback) {
1071 return GetSymbolVendorInstances().RegisterPlugin(name, description,
1072 create_callback);
1073}
1074
1075bool PluginManager::UnregisterPlugin(
1076 SymbolVendorCreateInstance create_callback) {
1077 return GetSymbolVendorInstances().UnregisterPlugin(create_callback);
1078}
1079
1080SymbolVendorCreateInstance
1081PluginManager::GetSymbolVendorCreateCallbackAtIndex(uint32_t idx) {
1082 return GetSymbolVendorInstances().GetCallbackAtIndex(idx);
1083}
1084
1085#pragma mark Trace
1086
1087struct TraceInstance
1088 : public PluginInstance<TraceCreateInstanceFromBundle> {
1089 TraceInstance(
1090 llvm::StringRef name, llvm::StringRef description,
1091 CallbackType create_callback_from_bundle,
1092 TraceCreateInstanceForLiveProcess create_callback_for_live_process,
1093 llvm::StringRef schema, DebuggerInitializeCallback debugger_init_callback)
1094 : PluginInstance<TraceCreateInstanceFromBundle>(
1095 name, description, create_callback_from_bundle,
1096 debugger_init_callback),
1097 schema(schema),
1098 create_callback_for_live_process(create_callback_for_live_process) {}
1099
1100 llvm::StringRef schema;
1101 TraceCreateInstanceForLiveProcess create_callback_for_live_process;
1102};
1103
1104typedef PluginInstances<TraceInstance> TraceInstances;
1105
1106static TraceInstances &GetTracePluginInstances() {
1107 static TraceInstances g_instances;
1108 return g_instances;
1109}
1110
1111bool PluginManager::RegisterPlugin(
1112 llvm::StringRef name, llvm::StringRef description,
1113 TraceCreateInstanceFromBundle create_callback_from_bundle,
1114 TraceCreateInstanceForLiveProcess create_callback_for_live_process,
1115 llvm::StringRef schema, DebuggerInitializeCallback debugger_init_callback) {
1116 return GetTracePluginInstances().RegisterPlugin(
1117 name, description, create_callback_from_bundle,
1118 create_callback_for_live_process, schema, debugger_init_callback);
1119}
1120
1121bool PluginManager::UnregisterPlugin(
1122 TraceCreateInstanceFromBundle create_callback_from_bundle) {
1123 return GetTracePluginInstances().UnregisterPlugin(
1124 create_callback_from_bundle);
1125}
1126
1127TraceCreateInstanceFromBundle
1128PluginManager::GetTraceCreateCallback(llvm::StringRef plugin_name) {
1129 return GetTracePluginInstances().GetCallbackForName(plugin_name);
1130}
1131
1132TraceCreateInstanceForLiveProcess
1133PluginManager::GetTraceCreateCallbackForLiveProcess(llvm::StringRef plugin_name) {
1134 for (const TraceInstance &instance : GetTracePluginInstances().GetInstances())
1135 if (instance.name == plugin_name)
1136 return instance.create_callback_for_live_process;
1137 return nullptr;
1138}
1139
1140llvm::StringRef PluginManager::GetTraceSchema(llvm::StringRef plugin_name) {
1141 for (const TraceInstance &instance : GetTracePluginInstances().GetInstances())
1142 if (instance.name == plugin_name)
1143 return instance.schema;
1144 return llvm::StringRef();
1145}
1146
1147llvm::StringRef PluginManager::GetTraceSchema(size_t index) {
1148 if (TraceInstance *instance =
1149 GetTracePluginInstances().GetInstanceAtIndex(index))
1150 return instance->schema;
1151 return llvm::StringRef();
1152}
1153
1154#pragma mark TraceExporter
1155
1156struct TraceExporterInstance
1157 : public PluginInstance<TraceExporterCreateInstance> {
1158 TraceExporterInstance(
1159 llvm::StringRef name, llvm::StringRef description,
1160 TraceExporterCreateInstance create_instance,
1161 ThreadTraceExportCommandCreator create_thread_trace_export_command)
1162 : PluginInstance<TraceExporterCreateInstance>(name, description,
1163 create_instance),
1164 create_thread_trace_export_command(create_thread_trace_export_command) {
1165 }
1166
1167 ThreadTraceExportCommandCreator create_thread_trace_export_command;
1168};
1169
1170typedef PluginInstances<TraceExporterInstance> TraceExporterInstances;
1171
1172static TraceExporterInstances &GetTraceExporterInstances() {
1173 static TraceExporterInstances g_instances;
1174 return g_instances;
1175}
1176
1177bool PluginManager::RegisterPlugin(
1178 llvm::StringRef name, llvm::StringRef description,
1179 TraceExporterCreateInstance create_callback,
1180 ThreadTraceExportCommandCreator create_thread_trace_export_command) {
1181 return GetTraceExporterInstances().RegisterPlugin(
1182 name, description, create_callback, create_thread_trace_export_command);
1183}
1184
1185TraceExporterCreateInstance
1186PluginManager::GetTraceExporterCreateCallback(llvm::StringRef plugin_name) {
1187 return GetTraceExporterInstances().GetCallbackForName(plugin_name);
1188}
1189
1190bool PluginManager::UnregisterPlugin(
1191 TraceExporterCreateInstance create_callback) {
1192 return GetTraceExporterInstances().UnregisterPlugin(create_callback);
1193}
1194
1195ThreadTraceExportCommandCreator
1196PluginManager::GetThreadTraceExportCommandCreatorAtIndex(uint32_t index) {
1197 if (TraceExporterInstance *instance =
1198 GetTraceExporterInstances().GetInstanceAtIndex(index))
1199 return instance->create_thread_trace_export_command;
1200 return nullptr;
1201}
1202
1203llvm::StringRef
1204PluginManager::GetTraceExporterPluginNameAtIndex(uint32_t index) {
1205 return GetTraceExporterInstances().GetNameAtIndex(index);
1206}
1207
1208#pragma mark UnwindAssembly
1209
1210typedef PluginInstance<UnwindAssemblyCreateInstance> UnwindAssemblyInstance;
1211typedef PluginInstances<UnwindAssemblyInstance> UnwindAssemblyInstances;
1212
1213static UnwindAssemblyInstances &GetUnwindAssemblyInstances() {
1214 static UnwindAssemblyInstances g_instances;
1215 return g_instances;
1216}
1217
1218bool PluginManager::RegisterPlugin(
1219 llvm::StringRef name, llvm::StringRef description,
1220 UnwindAssemblyCreateInstance create_callback) {
1221 return GetUnwindAssemblyInstances().RegisterPlugin(name, description,
1222 create_callback);
1223}
1224
1225bool PluginManager::UnregisterPlugin(
1226 UnwindAssemblyCreateInstance create_callback) {
1227 return GetUnwindAssemblyInstances().UnregisterPlugin(create_callback);
1228}
1229
1230UnwindAssemblyCreateInstance
1231PluginManager::GetUnwindAssemblyCreateCallbackAtIndex(uint32_t idx) {
1232 return GetUnwindAssemblyInstances().GetCallbackAtIndex(idx);
1233}
1234
1235#pragma mark MemoryHistory
1236
1237typedef PluginInstance<MemoryHistoryCreateInstance> MemoryHistoryInstance;
1238typedef PluginInstances<MemoryHistoryInstance> MemoryHistoryInstances;
1239
1240static MemoryHistoryInstances &GetMemoryHistoryInstances() {
1241 static MemoryHistoryInstances g_instances;
1242 return g_instances;
1243}
1244
1245bool PluginManager::RegisterPlugin(
1246 llvm::StringRef name, llvm::StringRef description,
1247 MemoryHistoryCreateInstance create_callback) {
1248 return GetMemoryHistoryInstances().RegisterPlugin(name, description,
1249 create_callback);
1250}
1251
1252bool PluginManager::UnregisterPlugin(
1253 MemoryHistoryCreateInstance create_callback) {
1254 return GetMemoryHistoryInstances().UnregisterPlugin(create_callback);
1255}
1256
1257MemoryHistoryCreateInstance
1258PluginManager::GetMemoryHistoryCreateCallbackAtIndex(uint32_t idx) {
1259 return GetMemoryHistoryInstances().GetCallbackAtIndex(idx);
1260}
1261
1262#pragma mark InstrumentationRuntime
1263
1264struct InstrumentationRuntimeInstance
1265 : public PluginInstance<InstrumentationRuntimeCreateInstance> {
1266 InstrumentationRuntimeInstance(
1267 llvm::StringRef name, llvm::StringRef description,
1268 CallbackType create_callback,
1269 InstrumentationRuntimeGetType get_type_callback)
1270 : PluginInstance<InstrumentationRuntimeCreateInstance>(name, description,
1271 create_callback),
1272 get_type_callback(get_type_callback) {}
1273
1274 InstrumentationRuntimeGetType get_type_callback = nullptr;
1275};
1276
1277typedef PluginInstances<InstrumentationRuntimeInstance>
1278 InstrumentationRuntimeInstances;
1279
1280static InstrumentationRuntimeInstances &GetInstrumentationRuntimeInstances() {
1281 static InstrumentationRuntimeInstances g_instances;
1282 return g_instances;
1283}
1284
1285bool PluginManager::RegisterPlugin(
1286 llvm::StringRef name, llvm::StringRef description,
1287 InstrumentationRuntimeCreateInstance create_callback,
1288 InstrumentationRuntimeGetType get_type_callback) {
1289 return GetInstrumentationRuntimeInstances().RegisterPlugin(
1290 name, description, create_callback, get_type_callback);
1291}
1292
1293bool PluginManager::UnregisterPlugin(
1294 InstrumentationRuntimeCreateInstance create_callback) {
1295 return GetInstrumentationRuntimeInstances().UnregisterPlugin(create_callback);
1296}
1297
1298InstrumentationRuntimeGetType
1299PluginManager::GetInstrumentationRuntimeGetTypeCallbackAtIndex(uint32_t idx) {
1300 const auto &instances = GetInstrumentationRuntimeInstances().GetInstances();
1301 if (idx < instances.size())
1302 return instances[idx].get_type_callback;
1303 return nullptr;
1304}
1305
1306InstrumentationRuntimeCreateInstance
1307PluginManager::GetInstrumentationRuntimeCreateCallbackAtIndex(uint32_t idx) {
1308 return GetInstrumentationRuntimeInstances().GetCallbackAtIndex(idx);
1309}
1310
1311#pragma mark TypeSystem
1312
1313struct TypeSystemInstance : public PluginInstance<TypeSystemCreateInstance> {
1314 TypeSystemInstance(llvm::StringRef name, llvm::StringRef description,
1315 CallbackType create_callback,
1316 LanguageSet supported_languages_for_types,
1317 LanguageSet supported_languages_for_expressions)
1318 : PluginInstance<TypeSystemCreateInstance>(name, description,
1319 create_callback),
1320 supported_languages_for_types(supported_languages_for_types),
1321 supported_languages_for_expressions(
1322 supported_languages_for_expressions) {}
1323
1324 LanguageSet supported_languages_for_types;
1325 LanguageSet supported_languages_for_expressions;
1326};
1327
1328typedef PluginInstances<TypeSystemInstance> TypeSystemInstances;
1329
1330static TypeSystemInstances &GetTypeSystemInstances() {
1331 static TypeSystemInstances g_instances;
1332 return g_instances;
1333}
1334
1335bool PluginManager::RegisterPlugin(
1336 llvm::StringRef name, llvm::StringRef description,
1337 TypeSystemCreateInstance create_callback,
1338 LanguageSet supported_languages_for_types,
1339 LanguageSet supported_languages_for_expressions) {
1340 return GetTypeSystemInstances().RegisterPlugin(
1
Calling 'PluginInstances::RegisterPlugin'
1341 name, description, create_callback, supported_languages_for_types,
1342 supported_languages_for_expressions);
1343}
1344
1345bool PluginManager::UnregisterPlugin(TypeSystemCreateInstance create_callback) {
1346 return GetTypeSystemInstances().UnregisterPlugin(create_callback);
1347}
1348
1349TypeSystemCreateInstance
1350PluginManager::GetTypeSystemCreateCallbackAtIndex(uint32_t idx) {
1351 return GetTypeSystemInstances().GetCallbackAtIndex(idx);
1352}
1353
1354LanguageSet PluginManager::GetAllTypeSystemSupportedLanguagesForTypes() {
1355 const auto &instances = GetTypeSystemInstances().GetInstances();
1356 LanguageSet all;
1357 for (unsigned i = 0; i < instances.size(); ++i)
1358 all.bitvector |= instances[i].supported_languages_for_types.bitvector;
1359 return all;
1360}
1361
1362LanguageSet PluginManager::GetAllTypeSystemSupportedLanguagesForExpressions() {
1363 const auto &instances = GetTypeSystemInstances().GetInstances();
1364 LanguageSet all;
1365 for (unsigned i = 0; i < instances.size(); ++i)
1366 all.bitvector |= instances[i].supported_languages_for_expressions.bitvector;
1367 return all;
1368}
1369
1370#pragma mark REPL
1371
1372struct REPLInstance : public PluginInstance<REPLCreateInstance> {
1373 REPLInstance(llvm::StringRef name, llvm::StringRef description,
1374 CallbackType create_callback, LanguageSet supported_languages)
1375 : PluginInstance<REPLCreateInstance>(name, description, create_callback),
1376 supported_languages(supported_languages) {}
1377
1378 LanguageSet supported_languages;
1379};
1380
1381typedef PluginInstances<REPLInstance> REPLInstances;
1382
1383static REPLInstances &GetREPLInstances() {
1384 static REPLInstances g_instances;
1385 return g_instances;
1386}
1387
1388bool PluginManager::RegisterPlugin(llvm::StringRef name, llvm::StringRef description,
1389 REPLCreateInstance create_callback,
1390 LanguageSet supported_languages) {
1391 return GetREPLInstances().RegisterPlugin(name, description, create_callback,
1392 supported_languages);
1393}
1394
1395bool PluginManager::UnregisterPlugin(REPLCreateInstance create_callback) {
1396 return GetREPLInstances().UnregisterPlugin(create_callback);
1397}
1398
1399REPLCreateInstance PluginManager::GetREPLCreateCallbackAtIndex(uint32_t idx) {
1400 return GetREPLInstances().GetCallbackAtIndex(idx);
1401}
1402
1403LanguageSet PluginManager::GetREPLSupportedLanguagesAtIndex(uint32_t idx) {
1404 const auto &instances = GetREPLInstances().GetInstances();
1405 return idx < instances.size() ? instances[idx].supported_languages
1406 : LanguageSet();
1407}
1408
1409LanguageSet PluginManager::GetREPLAllTypeSystemSupportedLanguages() {
1410 const auto &instances = GetREPLInstances().GetInstances();
1411 LanguageSet all;
1412 for (unsigned i = 0; i < instances.size(); ++i)
1413 all.bitvector |= instances[i].supported_languages.bitvector;
1414 return all;
1415}
1416
1417#pragma mark PluginManager
1418
1419void PluginManager::DebuggerInitialize(Debugger &debugger) {
1420 GetDynamicLoaderInstances().PerformDebuggerCallback(debugger);
1421 GetJITLoaderInstances().PerformDebuggerCallback(debugger);
1422 GetObjectFileInstances().PerformDebuggerCallback(debugger);
1423 GetPlatformInstances().PerformDebuggerCallback(debugger);
1424 GetProcessInstances().PerformDebuggerCallback(debugger);
1425 GetSymbolFileInstances().PerformDebuggerCallback(debugger);
1426 GetOperatingSystemInstances().PerformDebuggerCallback(debugger);
1427 GetStructuredDataPluginInstances().PerformDebuggerCallback(debugger);
1428 GetTracePluginInstances().PerformDebuggerCallback(debugger);
1429}
1430
1431// This is the preferred new way to register plugin specific settings. e.g.
1432// This will put a plugin's settings under e.g.
1433// "plugin.<plugin_type_name>.<plugin_type_desc>.SETTINGNAME".
1434static lldb::OptionValuePropertiesSP
1435GetDebuggerPropertyForPlugins(Debugger &debugger, ConstString plugin_type_name,
1436 llvm::StringRef plugin_type_desc,
1437 bool can_create) {
1438 lldb::OptionValuePropertiesSP parent_properties_sp(
1439 debugger.GetValueProperties());
1440 if (parent_properties_sp) {
1441 static ConstString g_property_name("plugin");
1442
1443 OptionValuePropertiesSP plugin_properties_sp =
1444 parent_properties_sp->GetSubProperty(nullptr, g_property_name);
1445 if (!plugin_properties_sp && can_create) {
1446 plugin_properties_sp =
1447 std::make_shared<OptionValueProperties>(g_property_name);
1448 parent_properties_sp->AppendProperty(g_property_name,
1449 "Settings specify to plugins.", true,
1450 plugin_properties_sp);
1451 }
1452
1453 if (plugin_properties_sp) {
1454 lldb::OptionValuePropertiesSP plugin_type_properties_sp =
1455 plugin_properties_sp->GetSubProperty(nullptr, plugin_type_name);
1456 if (!plugin_type_properties_sp && can_create) {
1457 plugin_type_properties_sp =
1458 std::make_shared<OptionValueProperties>(plugin_type_name);
1459 plugin_properties_sp->AppendProperty(plugin_type_name, plugin_type_desc,
1460 true, plugin_type_properties_sp);
1461 }
1462 return plugin_type_properties_sp;
1463 }
1464 }
1465 return lldb::OptionValuePropertiesSP();
1466}
1467
1468// This is deprecated way to register plugin specific settings. e.g.
1469// "<plugin_type_name>.plugin.<plugin_type_desc>.SETTINGNAME" and Platform
1470// generic settings would be under "platform.SETTINGNAME".
1471static lldb::OptionValuePropertiesSP GetDebuggerPropertyForPluginsOldStyle(
1472 Debugger &debugger, ConstString plugin_type_name,
1473 llvm::StringRef plugin_type_desc, bool can_create) {
1474 static ConstString g_property_name("plugin");
1475 lldb::OptionValuePropertiesSP parent_properties_sp(
1476 debugger.GetValueProperties());
1477 if (parent_properties_sp) {
1478 OptionValuePropertiesSP plugin_properties_sp =
1479 parent_properties_sp->GetSubProperty(nullptr, plugin_type_name);
1480 if (!plugin_properties_sp && can_create) {
1481 plugin_properties_sp =
1482 std::make_shared<OptionValueProperties>(plugin_type_name);
1483 parent_properties_sp->AppendProperty(plugin_type_name, plugin_type_desc,
1484 true, plugin_properties_sp);
1485 }
1486
1487 if (plugin_properties_sp) {
1488 lldb::OptionValuePropertiesSP plugin_type_properties_sp =
1489 plugin_properties_sp->GetSubProperty(nullptr, g_property_name);
1490 if (!plugin_type_properties_sp && can_create) {
1491 plugin_type_properties_sp =
1492 std::make_shared<OptionValueProperties>(g_property_name);
1493 plugin_properties_sp->AppendProperty(g_property_name,
1494 "Settings specific to plugins",
1495 true, plugin_type_properties_sp);
1496 }
1497 return plugin_type_properties_sp;
1498 }
1499 }
1500 return lldb::OptionValuePropertiesSP();
1501}
1502
1503namespace {
1504
1505typedef lldb::OptionValuePropertiesSP
1506GetDebuggerPropertyForPluginsPtr(Debugger &, ConstString, llvm::StringRef,
1507 bool can_create);
1508}
1509
1510static lldb::OptionValuePropertiesSP
1511GetSettingForPlugin(Debugger &debugger, ConstString setting_name,
1512 ConstString plugin_type_name,
1513 GetDebuggerPropertyForPluginsPtr get_debugger_property =
1514 GetDebuggerPropertyForPlugins) {
1515 lldb::OptionValuePropertiesSP properties_sp;
1516 lldb::OptionValuePropertiesSP plugin_type_properties_sp(get_debugger_property(
1517 debugger, plugin_type_name,
1518 "", // not creating to so we don't need the description
1519 false));
1520 if (plugin_type_properties_sp)
1521 properties_sp =
1522 plugin_type_properties_sp->GetSubProperty(nullptr, setting_name);
1523 return properties_sp;
1524}
1525
1526static bool
1527CreateSettingForPlugin(Debugger &debugger, ConstString plugin_type_name,
1528 llvm::StringRef plugin_type_desc,
1529 const lldb::OptionValuePropertiesSP &properties_sp,
1530 llvm::StringRef description, bool is_global_property,
1531 GetDebuggerPropertyForPluginsPtr get_debugger_property =
1532 GetDebuggerPropertyForPlugins) {
1533 if (properties_sp) {
1534 lldb::OptionValuePropertiesSP plugin_type_properties_sp(
1535 get_debugger_property(debugger, plugin_type_name, plugin_type_desc,
1536 true));
1537 if (plugin_type_properties_sp) {
1538 plugin_type_properties_sp->AppendProperty(properties_sp->GetName(),
1539 description, is_global_property,
1540 properties_sp);
1541 return true;
1542 }
1543 }
1544 return false;
1545}
1546
1547static const char *kDynamicLoaderPluginName("dynamic-loader");
1548static const char *kPlatformPluginName("platform");
1549static const char *kProcessPluginName("process");
1550static const char *kTracePluginName("trace");
1551static const char *kObjectFilePluginName("object-file");
1552static const char *kSymbolFilePluginName("symbol-file");
1553static const char *kJITLoaderPluginName("jit-loader");
1554static const char *kStructuredDataPluginName("structured-data");
1555
1556lldb::OptionValuePropertiesSP
1557PluginManager::GetSettingForDynamicLoaderPlugin(Debugger &debugger,
1558 ConstString setting_name) {
1559 return GetSettingForPlugin(debugger, setting_name,
1560 ConstString(kDynamicLoaderPluginName));
1561}
1562
1563bool PluginManager::CreateSettingForDynamicLoaderPlugin(
1564 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
1565 llvm::StringRef description, bool is_global_property) {
1566 return CreateSettingForPlugin(debugger, ConstString(kDynamicLoaderPluginName),
1567 "Settings for dynamic loader plug-ins",
1568 properties_sp, description, is_global_property);
1569}
1570
1571lldb::OptionValuePropertiesSP
1572PluginManager::GetSettingForPlatformPlugin(Debugger &debugger,
1573 ConstString setting_name) {
1574 return GetSettingForPlugin(debugger, setting_name,
1575 ConstString(kPlatformPluginName),
1576 GetDebuggerPropertyForPluginsOldStyle);
1577}
1578
1579bool PluginManager::CreateSettingForPlatformPlugin(
1580 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
1581 llvm::StringRef description, bool is_global_property) {
1582 return CreateSettingForPlugin(debugger, ConstString(kPlatformPluginName),
1583 "Settings for platform plug-ins", properties_sp,
1584 description, is_global_property,
1585 GetDebuggerPropertyForPluginsOldStyle);
1586}
1587
1588lldb::OptionValuePropertiesSP
1589PluginManager::GetSettingForProcessPlugin(Debugger &debugger,
1590 ConstString setting_name) {
1591 return GetSettingForPlugin(debugger, setting_name,
1592 ConstString(kProcessPluginName));
1593}
1594
1595bool PluginManager::CreateSettingForProcessPlugin(
1596 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
1597 llvm::StringRef description, bool is_global_property) {
1598 return CreateSettingForPlugin(debugger, ConstString(kProcessPluginName),
1599 "Settings for process plug-ins", properties_sp,
1600 description, is_global_property);
1601}
1602
1603bool PluginManager::CreateSettingForTracePlugin(
1604 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
1605 llvm::StringRef description, bool is_global_property) {
1606 return CreateSettingForPlugin(debugger, ConstString(kTracePluginName),
1607 "Settings for trace plug-ins", properties_sp,
1608 description, is_global_property);
1609}
1610
1611lldb::OptionValuePropertiesSP
1612PluginManager::GetSettingForObjectFilePlugin(Debugger &debugger,
1613 ConstString setting_name) {
1614 return GetSettingForPlugin(debugger, setting_name,
1615 ConstString(kObjectFilePluginName));
1616}
1617
1618bool PluginManager::CreateSettingForObjectFilePlugin(
1619 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
1620 llvm::StringRef description, bool is_global_property) {
1621 return CreateSettingForPlugin(debugger, ConstString(kObjectFilePluginName),
1622 "Settings for object file plug-ins",
1623 properties_sp, description, is_global_property);
1624}
1625
1626lldb::OptionValuePropertiesSP
1627PluginManager::GetSettingForSymbolFilePlugin(Debugger &debugger,
1628 ConstString setting_name) {
1629 return GetSettingForPlugin(debugger, setting_name,
1630 ConstString(kSymbolFilePluginName));
1631}
1632
1633bool PluginManager::CreateSettingForSymbolFilePlugin(
1634 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
1635 llvm::StringRef description, bool is_global_property) {
1636 return CreateSettingForPlugin(debugger, ConstString(kSymbolFilePluginName),
1637 "Settings for symbol file plug-ins",
1638 properties_sp, description, is_global_property);
1639}
1640
1641lldb::OptionValuePropertiesSP
1642PluginManager::GetSettingForJITLoaderPlugin(Debugger &debugger,
1643 ConstString setting_name) {
1644 return GetSettingForPlugin(debugger, setting_name,
1645 ConstString(kJITLoaderPluginName));
1646}
1647
1648bool PluginManager::CreateSettingForJITLoaderPlugin(
1649 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
1650 llvm::StringRef description, bool is_global_property) {
1651 return CreateSettingForPlugin(debugger, ConstString(kJITLoaderPluginName),
1652 "Settings for JIT loader plug-ins",
1653 properties_sp, description, is_global_property);
1654}
1655
1656static const char *kOperatingSystemPluginName("os");
1657
1658lldb::OptionValuePropertiesSP
1659PluginManager::GetSettingForOperatingSystemPlugin(Debugger &debugger,
1660 ConstString setting_name) {
1661 lldb::OptionValuePropertiesSP properties_sp;
1662 lldb::OptionValuePropertiesSP plugin_type_properties_sp(
1663 GetDebuggerPropertyForPlugins(
1664 debugger, ConstString(kOperatingSystemPluginName),
1665 "", // not creating to so we don't need the description
1666 false));
1667 if (plugin_type_properties_sp)
1668 properties_sp =
1669 plugin_type_properties_sp->GetSubProperty(nullptr, setting_name);
1670 return properties_sp;
1671}
1672
1673bool PluginManager::CreateSettingForOperatingSystemPlugin(
1674 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
1675 llvm::StringRef description, bool is_global_property) {
1676 if (properties_sp) {
1677 lldb::OptionValuePropertiesSP plugin_type_properties_sp(
1678 GetDebuggerPropertyForPlugins(
1679 debugger, ConstString(kOperatingSystemPluginName),
1680 "Settings for operating system plug-ins", true));
1681 if (plugin_type_properties_sp) {
1682 plugin_type_properties_sp->AppendProperty(properties_sp->GetName(),
1683 description, is_global_property,
1684 properties_sp);
1685 return true;
1686 }
1687 }
1688 return false;
1689}
1690
1691lldb::OptionValuePropertiesSP
1692PluginManager::GetSettingForStructuredDataPlugin(Debugger &debugger,
1693 ConstString setting_name) {
1694 return GetSettingForPlugin(debugger, setting_name,
1695 ConstString(kStructuredDataPluginName));
1696}
1697
1698bool PluginManager::CreateSettingForStructuredDataPlugin(
1699 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
1700 llvm::StringRef description, bool is_global_property) {
1701 return CreateSettingForPlugin(debugger,
1702 ConstString(kStructuredDataPluginName),
1703 "Settings for structured data plug-ins",
1704 properties_sp, description, is_global_property);
1705}

/build/source/lldb/include/lldb/Symbol/TypeSystem.h

1//===-- TypeSystem.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_SYMBOL_TYPESYSTEM_H
10#define LLDB_SYMBOL_TYPESYSTEM_H
11
12#include <functional>
13#include <mutex>
14#include <optional>
15#include <string>
16
17#include "llvm/ADT/APFloat.h"
18#include "llvm/ADT/APSInt.h"
19#include "llvm/ADT/DenseMap.h"
20#include "llvm/ADT/SmallBitVector.h"
21#include "llvm/Support/Casting.h"
22#include "llvm/Support/Error.h"
23#include "llvm/Support/JSON.h"
24
25#include "lldb/Core/PluginInterface.h"
26#include "lldb/Expression/Expression.h"
27#include "lldb/Symbol/CompilerDecl.h"
28#include "lldb/Symbol/CompilerDeclContext.h"
29#include "lldb/lldb-private.h"
30
31class DWARFDIE;
32class DWARFASTParser;
33class PDBASTParser;
34
35namespace lldb_private {
36namespace npdb {
37 class PdbAstBuilder;
38} // namespace npdb
39
40/// A SmallBitVector that represents a set of source languages (\p
41/// lldb::LanguageType). Each lldb::LanguageType is represented by
42/// the bit with the position of its enumerator. The largest
43/// LanguageType is < 64, so this is space-efficient and on 64-bit
44/// architectures a LanguageSet can be completely stack-allocated.
45struct LanguageSet {
46 llvm::SmallBitVector bitvector;
47 LanguageSet();
48
49 /// If the set contains a single language only, return it.
50 std::optional<lldb::LanguageType> GetSingularLanguage();
51 void Insert(lldb::LanguageType language);
52 bool Empty() const;
53 size_t Size() const;
54 bool operator[](unsigned i) const;
55};
56
57/// Interface for representing a type system.
58///
59/// Implemented by language plugins to define the type system for a given
60/// language.
61///
62/// This interface extensively used opaque pointers to prevent that generic
63/// LLDB code has dependencies on language plugins. The type and semantics of
64/// these opaque pointers are defined by the TypeSystem implementation inside
65/// the respective language plugin. Opaque pointers from one TypeSystem
66/// instance should never be passed to a different TypeSystem instance (even
67/// when the language plugin for both TypeSystem instances is the same).
68///
69/// Most of the functions in this class should not be called directly but only
70/// called by their respective counterparts in CompilerType, CompilerDecl and
71/// CompilerDeclContext.
72///
73/// \see lldb_private::CompilerType
74/// \see lldb_private::CompilerDecl
75/// \see lldb_private::CompilerDeclContext
76class TypeSystem : public PluginInterface,
77 public std::enable_shared_from_this<TypeSystem> {
78public:
79 // Constructors and Destructors
80 TypeSystem();
81 ~TypeSystem() override;
82
83 // LLVM RTTI support
84 virtual bool isA(const void *ClassID) const = 0;
85
86 static lldb::TypeSystemSP CreateInstance(lldb::LanguageType language,
87 Module *module);
88
89 static lldb::TypeSystemSP CreateInstance(lldb::LanguageType language,
90 Target *target);
91
92 /// Free up any resources associated with this TypeSystem. Done before
93 /// removing all the TypeSystems from the TypeSystemMap.
94 virtual void Finalize() {}
95
96 virtual DWARFASTParser *GetDWARFParser() { return nullptr; }
97 virtual PDBASTParser *GetPDBParser() { return nullptr; }
98 virtual npdb::PdbAstBuilder *GetNativePDBParser() { return nullptr; }
99
100 virtual SymbolFile *GetSymbolFile() const { return m_sym_file; }
101
102 virtual void SetSymbolFile(SymbolFile *sym_file) { m_sym_file = sym_file; }
103
104 // CompilerDecl functions
105 virtual ConstString DeclGetName(void *opaque_decl) = 0;
106
107 virtual ConstString DeclGetMangledName(void *opaque_decl);
108
109 virtual CompilerDeclContext DeclGetDeclContext(void *opaque_decl);
110
111 virtual CompilerType DeclGetFunctionReturnType(void *opaque_decl);
112
113 virtual size_t DeclGetFunctionNumArguments(void *opaque_decl);
114
115 virtual CompilerType DeclGetFunctionArgumentType(void *opaque_decl,
116 size_t arg_idx);
117
118 virtual CompilerType GetTypeForDecl(void *opaque_decl) = 0;
119
120 // CompilerDeclContext functions
121
122 virtual std::vector<CompilerDecl>
123 DeclContextFindDeclByName(void *opaque_decl_ctx, ConstString name,
124 const bool ignore_imported_decls);
125
126 virtual ConstString DeclContextGetName(void *opaque_decl_ctx) = 0;
127
128 virtual ConstString
129 DeclContextGetScopeQualifiedName(void *opaque_decl_ctx) = 0;
130
131 virtual bool DeclContextIsClassMethod(void *opaque_decl_ctx) = 0;
132
133 virtual bool DeclContextIsContainedInLookup(void *opaque_decl_ctx,
134 void *other_opaque_decl_ctx) = 0;
135
136 virtual lldb::LanguageType DeclContextGetLanguage(void *opaque_decl_ctx) = 0;
137
138 // Tests
139#ifndef NDEBUG
140 /// Verify the integrity of the type to catch CompilerTypes that mix
141 /// and match invalid TypeSystem/Opaque type pairs.
142 virtual bool Verify(lldb::opaque_compiler_type_t type) = 0;
143#endif
144
145 virtual bool IsArrayType(lldb::opaque_compiler_type_t type,
146 CompilerType *element_type, uint64_t *size,
147 bool *is_incomplete) = 0;
148
149 virtual bool IsAggregateType(lldb::opaque_compiler_type_t type) = 0;
150
151 virtual bool IsAnonymousType(lldb::opaque_compiler_type_t type);
152
153 virtual bool IsCharType(lldb::opaque_compiler_type_t type) = 0;
154
155 virtual bool IsCompleteType(lldb::opaque_compiler_type_t type) = 0;
156
157 virtual bool IsDefined(lldb::opaque_compiler_type_t type) = 0;
158
159 virtual bool IsFloatingPointType(lldb::opaque_compiler_type_t type,
160 uint32_t &count, bool &is_complex) = 0;
161
162 virtual bool IsFunctionType(lldb::opaque_compiler_type_t type) = 0;
163
164 virtual size_t
165 GetNumberOfFunctionArguments(lldb::opaque_compiler_type_t type) = 0;
166
167 virtual CompilerType
168 GetFunctionArgumentAtIndex(lldb::opaque_compiler_type_t type,
169 const size_t index) = 0;
170
171 virtual bool IsFunctionPointerType(lldb::opaque_compiler_type_t type) = 0;
172
173 virtual bool
174 IsMemberFunctionPointerType(lldb::opaque_compiler_type_t type) = 0;
175
176 virtual bool IsBlockPointerType(lldb::opaque_compiler_type_t type,
177 CompilerType *function_pointer_type_ptr) = 0;
178
179 virtual bool IsIntegerType(lldb::opaque_compiler_type_t type,
180 bool &is_signed) = 0;
181
182 virtual bool IsEnumerationType(lldb::opaque_compiler_type_t type,
183 bool &is_signed) {
184 is_signed = false;
185 return false;
186 }
187
188 virtual bool IsScopedEnumerationType(lldb::opaque_compiler_type_t type) = 0;
189
190 virtual bool IsPossibleDynamicType(lldb::opaque_compiler_type_t type,
191 CompilerType *target_type, // Can pass NULL
192 bool check_cplusplus, bool check_objc) = 0;
193
194 virtual bool IsPointerType(lldb::opaque_compiler_type_t type,
195 CompilerType *pointee_type) = 0;
196
197 virtual bool IsScalarType(lldb::opaque_compiler_type_t type) = 0;
198
199 virtual bool IsVoidType(lldb::opaque_compiler_type_t type) = 0;
200
201 virtual bool CanPassInRegisters(const CompilerType &type) = 0;
202
203 // TypeSystems can support more than one language
204 virtual bool SupportsLanguage(lldb::LanguageType language) = 0;
205
206 // Type Completion
207
208 virtual bool GetCompleteType(lldb::opaque_compiler_type_t type) = 0;
209
210 virtual bool IsForcefullyCompleted(lldb::opaque_compiler_type_t type) {
211 return false;
212 }
213
214 // AST related queries
215
216 virtual uint32_t GetPointerByteSize() = 0;
217
218 // Accessors
219
220 virtual ConstString GetTypeName(lldb::opaque_compiler_type_t type,
221 bool BaseOnly) = 0;
222
223 virtual ConstString GetDisplayTypeName(lldb::opaque_compiler_type_t type) = 0;
224
225 virtual uint32_t
226 GetTypeInfo(lldb::opaque_compiler_type_t type,
227 CompilerType *pointee_or_element_compiler_type) = 0;
228
229 virtual lldb::LanguageType
230 GetMinimumLanguage(lldb::opaque_compiler_type_t type) = 0;
231
232 virtual lldb::TypeClass GetTypeClass(lldb::opaque_compiler_type_t type) = 0;
233
234 // Creating related types
235
236 virtual CompilerType
237 GetArrayElementType(lldb::opaque_compiler_type_t type,
238 ExecutionContextScope *exe_scope) = 0;
239
240 virtual CompilerType GetArrayType(lldb::opaque_compiler_type_t type,
241 uint64_t size);
242
243 virtual CompilerType GetCanonicalType(lldb::opaque_compiler_type_t type) = 0;
244
245 virtual CompilerType
246 GetEnumerationIntegerType(lldb::opaque_compiler_type_t type) = 0;
247
248 // Returns -1 if this isn't a function of if the function doesn't have a
249 // prototype Returns a value >= 0 if there is a prototype.
250 virtual int GetFunctionArgumentCount(lldb::opaque_compiler_type_t type) = 0;
251
252 virtual CompilerType
253 GetFunctionArgumentTypeAtIndex(lldb::opaque_compiler_type_t type,
254 size_t idx) = 0;
255
256 virtual CompilerType
257 GetFunctionReturnType(lldb::opaque_compiler_type_t type) = 0;
258
259 virtual size_t GetNumMemberFunctions(lldb::opaque_compiler_type_t type) = 0;
260
261 virtual TypeMemberFunctionImpl
262 GetMemberFunctionAtIndex(lldb::opaque_compiler_type_t type, size_t idx) = 0;
263
264 virtual CompilerType GetPointeeType(lldb::opaque_compiler_type_t type) = 0;
265
266 virtual CompilerType GetPointerType(lldb::opaque_compiler_type_t type) = 0;
267
268 virtual CompilerType
269 GetLValueReferenceType(lldb::opaque_compiler_type_t type);
270
271 virtual CompilerType
272 GetRValueReferenceType(lldb::opaque_compiler_type_t type);
273
274 virtual CompilerType GetAtomicType(lldb::opaque_compiler_type_t type);
275
276 virtual CompilerType AddConstModifier(lldb::opaque_compiler_type_t type);
277
278 virtual CompilerType AddVolatileModifier(lldb::opaque_compiler_type_t type);
279
280 virtual CompilerType AddRestrictModifier(lldb::opaque_compiler_type_t type);
281
282 /// \param opaque_payload The m_payload field of Type, which may
283 /// carry TypeSystem-specific extra information.
284 virtual CompilerType CreateTypedef(lldb::opaque_compiler_type_t type,
285 const char *name,
286 const CompilerDeclContext &decl_ctx,
287 uint32_t opaque_payload);
288
289 // Exploring the type
290
291 virtual const llvm::fltSemantics &GetFloatTypeSemantics(size_t byte_size) = 0;
292
293 virtual std::optional<uint64_t>
294 GetBitSize(lldb::opaque_compiler_type_t type,
295 ExecutionContextScope *exe_scope) = 0;
296
297 virtual lldb::Encoding GetEncoding(lldb::opaque_compiler_type_t type,
298 uint64_t &count) = 0;
299
300 virtual lldb::Format GetFormat(lldb::opaque_compiler_type_t type) = 0;
301
302 virtual uint32_t GetNumChildren(lldb::opaque_compiler_type_t type,
303 bool omit_empty_base_classes,
304 const ExecutionContext *exe_ctx) = 0;
305
306 virtual CompilerType GetBuiltinTypeByName(ConstString name);
307
308 virtual lldb::BasicType
309 GetBasicTypeEnumeration(lldb::opaque_compiler_type_t type) = 0;
310
311 virtual void ForEachEnumerator(
312 lldb::opaque_compiler_type_t type,
313 std::function<bool(const CompilerType &integer_type,
314 ConstString name,
315 const llvm::APSInt &value)> const &callback) {}
316
317 virtual uint32_t GetNumFields(lldb::opaque_compiler_type_t type) = 0;
318
319 virtual CompilerType GetFieldAtIndex(lldb::opaque_compiler_type_t type,
320 size_t idx, std::string &name,
321 uint64_t *bit_offset_ptr,
322 uint32_t *bitfield_bit_size_ptr,
323 bool *is_bitfield_ptr) = 0;
324
325 virtual uint32_t
326 GetNumDirectBaseClasses(lldb::opaque_compiler_type_t type) = 0;
327
328 virtual uint32_t
329 GetNumVirtualBaseClasses(lldb::opaque_compiler_type_t type) = 0;
330
331 virtual CompilerType
332 GetDirectBaseClassAtIndex(lldb::opaque_compiler_type_t type, size_t idx,
333 uint32_t *bit_offset_ptr) = 0;
334
335 virtual CompilerType
336 GetVirtualBaseClassAtIndex(lldb::opaque_compiler_type_t type, size_t idx,
337 uint32_t *bit_offset_ptr) = 0;
338
339 virtual CompilerType GetChildCompilerTypeAtIndex(
340 lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, size_t idx,
341 bool transparent_pointers, bool omit_empty_base_classes,
342 bool ignore_array_bounds, std::string &child_name,
343 uint32_t &child_byte_size, int32_t &child_byte_offset,
344 uint32_t &child_bitfield_bit_size, uint32_t &child_bitfield_bit_offset,
345 bool &child_is_base_class, bool &child_is_deref_of_parent,
346 ValueObject *valobj, uint64_t &language_flags) = 0;
347
348 // Lookup a child given a name. This function will match base class names and
349 // member member names in "clang_type" only, not descendants.
350 virtual uint32_t GetIndexOfChildWithName(lldb::opaque_compiler_type_t type,
351 const char *name,
352 bool omit_empty_base_classes) = 0;
353
354 // Lookup a child member given a name. This function will match member names
355 // only and will descend into "clang_type" children in search for the first
356 // member in this class, or any base class that matches "name".
357 // TODO: Return all matches for a given name by returning a
358 // vector<vector<uint32_t>>
359 // so we catch all names that match a given child name, not just the first.
360 virtual size_t
361 GetIndexOfChildMemberWithName(lldb::opaque_compiler_type_t type,
362 const char *name, bool omit_empty_base_classes,
363 std::vector<uint32_t> &child_indexes) = 0;
364
365 virtual bool IsTemplateType(lldb::opaque_compiler_type_t type);
366
367 virtual size_t GetNumTemplateArguments(lldb::opaque_compiler_type_t type,
368 bool expand_pack);
369
370 virtual lldb::TemplateArgumentKind
371 GetTemplateArgumentKind(lldb::opaque_compiler_type_t type, size_t idx,
372 bool expand_pack);
373 virtual CompilerType
374 GetTypeTemplateArgument(lldb::opaque_compiler_type_t type, size_t idx,
375 bool expand_pack);
376 virtual std::optional<CompilerType::IntegralTemplateArgument>
377 GetIntegralTemplateArgument(lldb::opaque_compiler_type_t type, size_t idx,
378 bool expand_pack);
379
380 // Dumping types
381
382#ifndef NDEBUG
383 /// Convenience LLVM-style dump method for use in the debugger only.
384 LLVM_DUMP_METHOD__attribute__((noinline)) __attribute__((__used__)) virtual void
385 dump(lldb::opaque_compiler_type_t type) const = 0;
386#endif
387
388 virtual void DumpValue(lldb::opaque_compiler_type_t type,
389 ExecutionContext *exe_ctx, Stream *s,
390 lldb::Format format, const DataExtractor &data,
391 lldb::offset_t data_offset, size_t data_byte_size,
392 uint32_t bitfield_bit_size,
393 uint32_t bitfield_bit_offset, bool show_types,
394 bool show_summary, bool verbose, uint32_t depth) = 0;
395
396 virtual bool DumpTypeValue(lldb::opaque_compiler_type_t type, Stream *s,
397 lldb::Format format, const DataExtractor &data,
398 lldb::offset_t data_offset, size_t data_byte_size,
399 uint32_t bitfield_bit_size,
400 uint32_t bitfield_bit_offset,
401 ExecutionContextScope *exe_scope) = 0;
402
403 /// Dump the type to stdout.
404 virtual void DumpTypeDescription(
405 lldb::opaque_compiler_type_t type,
406 lldb::DescriptionLevel level = lldb::eDescriptionLevelFull) = 0;
407
408 /// Print a description of the type to a stream. The exact implementation
409 /// varies, but the expectation is that eDescriptionLevelFull returns a
410 /// source-like representation of the type, whereas eDescriptionLevelVerbose
411 /// does a dump of the underlying AST if applicable.
412 virtual void DumpTypeDescription(
413 lldb::opaque_compiler_type_t type, Stream *s,
414 lldb::DescriptionLevel level = lldb::eDescriptionLevelFull) = 0;
415
416 /// Dump a textual representation of the internal TypeSystem state to the
417 /// given stream.
418 ///
419 /// This should not modify the state of the TypeSystem if possible.
420 virtual void Dump(llvm::raw_ostream &output) = 0;
421
422 // TODO: These methods appear unused. Should they be removed?
423
424 virtual bool IsRuntimeGeneratedType(lldb::opaque_compiler_type_t type) = 0;
425
426 virtual void DumpSummary(lldb::opaque_compiler_type_t type,
427 ExecutionContext *exe_ctx, Stream *s,
428 const DataExtractor &data,
429 lldb::offset_t data_offset,
430 size_t data_byte_size) = 0;
431
432 // TODO: Determine if these methods should move to TypeSystemClang.
433
434 virtual bool IsPointerOrReferenceType(lldb::opaque_compiler_type_t type,
435 CompilerType *pointee_type) = 0;
436
437 virtual unsigned GetTypeQualifiers(lldb::opaque_compiler_type_t type) = 0;
438
439 virtual bool IsCStringType(lldb::opaque_compiler_type_t type,
440 uint32_t &length) = 0;
441
442 virtual std::optional<size_t>
443 GetTypeBitAlign(lldb::opaque_compiler_type_t type,
444 ExecutionContextScope *exe_scope) = 0;
445
446 virtual CompilerType GetBasicTypeFromAST(lldb::BasicType basic_type) = 0;
447
448 virtual CompilerType
449 GetBuiltinTypeForEncodingAndBitSize(lldb::Encoding encoding,
450 size_t bit_size) = 0;
451
452 virtual bool IsBeingDefined(lldb::opaque_compiler_type_t type) = 0;
453
454 virtual bool IsConst(lldb::opaque_compiler_type_t type) = 0;
455
456 virtual uint32_t IsHomogeneousAggregate(lldb::opaque_compiler_type_t type,
457 CompilerType *base_type_ptr) = 0;
458
459 virtual bool IsPolymorphicClass(lldb::opaque_compiler_type_t type) = 0;
460
461 virtual bool IsTypedefType(lldb::opaque_compiler_type_t type) = 0;
462
463 // If the current object represents a typedef type, get the underlying type
464 virtual CompilerType GetTypedefedType(lldb::opaque_compiler_type_t type) = 0;
465
466 virtual bool IsVectorType(lldb::opaque_compiler_type_t type,
467 CompilerType *element_type, uint64_t *size) = 0;
468
469 virtual CompilerType
470 GetFullyUnqualifiedType(lldb::opaque_compiler_type_t type) = 0;
471
472 virtual CompilerType
473 GetNonReferenceType(lldb::opaque_compiler_type_t type) = 0;
474
475 virtual bool IsReferenceType(lldb::opaque_compiler_type_t type,
476 CompilerType *pointee_type, bool *is_rvalue) = 0;
477
478 virtual bool
479 ShouldTreatScalarValueAsAddress(lldb::opaque_compiler_type_t type) {
480 return IsPointerOrReferenceType(type, nullptr);
481 }
482
483 virtual UserExpression *
484 GetUserExpression(llvm::StringRef expr, llvm::StringRef prefix,
485 lldb::LanguageType language,
486 Expression::ResultType desired_type,
487 const EvaluateExpressionOptions &options,
488 ValueObject *ctx_obj) {
489 return nullptr;
490 }
491
492 virtual FunctionCaller *GetFunctionCaller(const CompilerType &return_type,
493 const Address &function_address,
494 const ValueList &arg_value_list,
495 const char *name) {
496 return nullptr;
497 }
498
499 virtual std::unique_ptr<UtilityFunction>
500 CreateUtilityFunction(std::string text, std::string name);
501
502 virtual PersistentExpressionState *GetPersistentExpressionState() {
503 return nullptr;
504 }
505
506 virtual CompilerType GetTypeForFormatters(void *type);
507
508 virtual LazyBool ShouldPrintAsOneLiner(void *type, ValueObject *valobj);
509
510 // Type systems can have types that are placeholder types, which are meant to
511 // indicate the presence of a type, but offer no actual information about
512 // said types, and leave the burden of actually figuring type information out
513 // to dynamic type resolution. For instance a language with a generics
514 // system, can use placeholder types to indicate "type argument goes here",
515 // without promising uniqueness of the placeholder, nor attaching any
516 // actually idenfiable information to said placeholder. This API allows type
517 // systems to tell LLDB when such a type has been encountered In response,
518 // the debugger can react by not using this type as a cache entry in any
519 // type-specific way For instance, LLDB will currently not cache any
520 // formatters that are discovered on such a type as attributable to the
521 // meaningless type itself, instead preferring to use the dynamic type
522 virtual bool IsMeaninglessWithoutDynamicResolution(void *type);
523
524 virtual std::optional<llvm::json::Value> ReportStatistics();
525
526 bool GetHasForcefullyCompletedTypes() const {
527 return m_has_forcefully_completed_types;
528 }
529protected:
530 SymbolFile *m_sym_file = nullptr;
531 /// Used for reporting statistics.
532 bool m_has_forcefully_completed_types = false;
533};
534
535class TypeSystemMap {
536public:
537 TypeSystemMap();
538 ~TypeSystemMap();
539
540 // Clear calls Finalize on all the TypeSystems managed by this map, and then
541 // empties the map.
542 void Clear();
543
544 // Iterate through all of the type systems that are created. Return true from
545 // callback to keep iterating, false to stop iterating.
546 void ForEach(std::function<bool(lldb::TypeSystemSP)> const &callback);
547
548 llvm::Expected<lldb::TypeSystemSP>
549 GetTypeSystemForLanguage(lldb::LanguageType language, Module *module,
550 bool can_create);
551
552 llvm::Expected<lldb::TypeSystemSP>
553 GetTypeSystemForLanguage(lldb::LanguageType language, Target *target,
554 bool can_create);
555
556 /// Check all type systems in the map to see if any have forcefully completed
557 /// types;
558 bool GetHasForcefullyCompletedTypes() const;
559protected:
560 typedef llvm::DenseMap<uint16_t, lldb::TypeSystemSP> collection;
561 mutable std::mutex m_mutex; ///< A mutex to keep this object happy in
562 /// multi-threaded environments.
563 collection m_map;
564 bool m_clear_in_progress = false;
565
566private:
567 typedef llvm::function_ref<lldb::TypeSystemSP()> CreateCallback;
568 /// Finds the type system for the given language. If no type system could be
569 /// found for a language and a CreateCallback was provided, the value
570 /// returned by the callback will be treated as the TypeSystem for the
571 /// language.
572 ///
573 /// \param language The language for which the type system should be found.
574 /// \param create_callback A callback that will be called if no previously
575 /// created TypeSystem that fits the given language
576 /// could found. Can be omitted if a non-existent
577 /// type system should be treated as an error
578 /// instead.
579 /// \return The found type system or an error.
580 llvm::Expected<lldb::TypeSystemSP> GetTypeSystemForLanguage(
581 lldb::LanguageType language,
582 std::optional<CreateCallback> create_callback = std::nullopt);
583 };
584
585} // namespace lldb_private
586
587#endif // LLDB_SYMBOL_TYPESYSTEM_H

/build/source/llvm/include/llvm/ADT/SmallBitVector.h

1//===- llvm/ADT/SmallBitVector.h - 'Normally small' bit vectors -*- 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/// \file
10/// This file implements the SmallBitVector class.
11///
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_ADT_SMALLBITVECTOR_H
15#define LLVM_ADT_SMALLBITVECTOR_H
16
17#include "llvm/ADT/BitVector.h"
18#include "llvm/ADT/iterator_range.h"
19#include "llvm/Support/MathExtras.h"
20#include <algorithm>
21#include <cassert>
22#include <climits>
23#include <cstddef>
24#include <cstdint>
25#include <limits>
26#include <utility>
27
28namespace llvm {
29
30/// This is a 'bitvector' (really, a variable-sized bit array), optimized for
31/// the case when the array is small. It contains one pointer-sized field, which
32/// is directly used as a plain collection of bits when possible, or as a
33/// pointer to a larger heap-allocated array when necessary. This allows normal
34/// "small" cases to be fast without losing generality for large inputs.
35class SmallBitVector {
36 // TODO: In "large" mode, a pointer to a BitVector is used, leading to an
37 // unnecessary level of indirection. It would be more efficient to use a
38 // pointer to memory containing size, allocation size, and the array of bits.
39 uintptr_t X = 1;
40
41 enum {
42 // The number of bits in this class.
43 NumBaseBits = sizeof(uintptr_t) * CHAR_BIT8,
44
45 // One bit is used to discriminate between small and large mode. The
46 // remaining bits are used for the small-mode representation.
47 SmallNumRawBits = NumBaseBits - 1,
48
49 // A few more bits are used to store the size of the bit set in small mode.
50 // Theoretically this is a ceil-log2. These bits are encoded in the most
51 // significant bits of the raw bits.
52 SmallNumSizeBits = (NumBaseBits == 32 ? 5 :
53 NumBaseBits == 64 ? 6 :
54 SmallNumRawBits),
55
56 // The remaining bits are used to store the actual set in small mode.
57 SmallNumDataBits = SmallNumRawBits - SmallNumSizeBits
58 };
59
60 static_assert(NumBaseBits == 64 || NumBaseBits == 32,
61 "Unsupported word size");
62
63public:
64 using size_type = uintptr_t;
65
66 // Encapsulation of a single bit.
67 class reference {
68 SmallBitVector &TheVector;
69 unsigned BitPos;
70
71 public:
72 reference(SmallBitVector &b, unsigned Idx) : TheVector(b), BitPos(Idx) {}
73
74 reference(const reference&) = default;
75
76 reference& operator=(reference t) {
77 *this = bool(t);
78 return *this;
79 }
80
81 reference& operator=(bool t) {
82 if (t)
83 TheVector.set(BitPos);
84 else
85 TheVector.reset(BitPos);
86 return *this;
87 }
88
89 operator bool() const {
90 return const_cast<const SmallBitVector &>(TheVector).operator[](BitPos);
91 }
92 };
93
94private:
95 BitVector *getPointer() const {
96 assert(!isSmall())(static_cast <bool> (!isSmall()) ? void (0) : __assert_fail
("!isSmall()", "llvm/include/llvm/ADT/SmallBitVector.h", 96,
__extension__ __PRETTY_FUNCTION__))
;
26
Assuming the condition is true
27
'?' condition is true
97 return reinterpret_cast<BitVector *>(X);
28
Use of memory after it is freed
98 }
99
100 void switchToSmall(uintptr_t NewSmallBits, size_type NewSize) {
101 X = 1;
102 setSmallSize(NewSize);
103 setSmallBits(NewSmallBits);
104 }
105
106 void switchToLarge(BitVector *BV) {
107 X = reinterpret_cast<uintptr_t>(BV);
108 assert(!isSmall() && "Tried to use an unaligned pointer")(static_cast <bool> (!isSmall() && "Tried to use an unaligned pointer"
) ? void (0) : __assert_fail ("!isSmall() && \"Tried to use an unaligned pointer\""
, "llvm/include/llvm/ADT/SmallBitVector.h", 108, __extension__
__PRETTY_FUNCTION__))
;
109 }
110
111 // Return all the bits used for the "small" representation; this includes
112 // bits for the size as well as the element bits.
113 uintptr_t getSmallRawBits() const {
114 assert(isSmall())(static_cast <bool> (isSmall()) ? void (0) : __assert_fail
("isSmall()", "llvm/include/llvm/ADT/SmallBitVector.h", 114,
__extension__ __PRETTY_FUNCTION__))
;
115 return X >> 1;
116 }
117
118 void setSmallRawBits(uintptr_t NewRawBits) {
119 assert(isSmall())(static_cast <bool> (isSmall()) ? void (0) : __assert_fail
("isSmall()", "llvm/include/llvm/ADT/SmallBitVector.h", 119,
__extension__ __PRETTY_FUNCTION__))
;
120 X = (NewRawBits << 1) | uintptr_t(1);
121 }
122
123 // Return the size.
124 size_type getSmallSize() const {
125 return getSmallRawBits() >> SmallNumDataBits;
126 }
127
128 void setSmallSize(size_type Size) {
129 setSmallRawBits(getSmallBits() | (Size << SmallNumDataBits));
130 }
131
132 // Return the element bits.
133 uintptr_t getSmallBits() const {
134 return getSmallRawBits() & ~(~uintptr_t(0) << getSmallSize());
135 }
136
137 void setSmallBits(uintptr_t NewBits) {
138 setSmallRawBits((NewBits & ~(~uintptr_t(0) << getSmallSize())) |
139 (getSmallSize() << SmallNumDataBits));
140 }
141
142public:
143 /// Creates an empty bitvector.
144 SmallBitVector() = default;
145
146 /// Creates a bitvector of specified number of bits. All bits are initialized
147 /// to the specified value.
148 explicit SmallBitVector(unsigned s, bool t = false) {
149 if (s <= SmallNumDataBits)
150 switchToSmall(t ? ~uintptr_t(0) : 0, s);
151 else
152 switchToLarge(new BitVector(s, t));
153 }
154
155 /// SmallBitVector copy ctor.
156 SmallBitVector(const SmallBitVector &RHS) {
157 if (RHS.isSmall())
8
Assuming the condition is false
9
Taking false branch
158 X = RHS.X;
159 else
160 switchToLarge(new BitVector(*RHS.getPointer()));
10
Memory is allocated
161 }
162
163 SmallBitVector(SmallBitVector &&RHS) : X(RHS.X) {
164 RHS.X = 1;
165 }
166
167 ~SmallBitVector() {
168 if (!isSmall())
15
Assuming the condition is true
16
Taking true branch
23
Assuming the condition is true
24
Taking true branch
169 delete getPointer();
17
Memory is released
25
Calling 'SmallBitVector::getPointer'
170 }
171
172 using const_set_bits_iterator = const_set_bits_iterator_impl<SmallBitVector>;
173 using set_iterator = const_set_bits_iterator;
174
175 const_set_bits_iterator set_bits_begin() const {
176 return const_set_bits_iterator(*this);
177 }
178
179 const_set_bits_iterator set_bits_end() const {
180 return const_set_bits_iterator(*this, -1);
181 }
182
183 iterator_range<const_set_bits_iterator> set_bits() const {
184 return make_range(set_bits_begin(), set_bits_end());
185 }
186
187 bool isSmall() const { return X & uintptr_t(1); }
188
189 /// Tests whether there are no bits in this bitvector.
190 bool empty() const {
191 return isSmall() ? getSmallSize() == 0 : getPointer()->empty();
192 }
193
194 /// Returns the number of bits in this bitvector.
195 size_type size() const {
196 return isSmall() ? getSmallSize() : getPointer()->size();
197 }
198
199 /// Returns the number of bits which are set.
200 size_type count() const {
201 if (isSmall()) {
202 uintptr_t Bits = getSmallBits();
203 return llvm::popcount(Bits);
204 }
205 return getPointer()->count();
206 }
207
208 /// Returns true if any bit is set.
209 bool any() const {
210 if (isSmall())
211 return getSmallBits() != 0;
212 return getPointer()->any();
213 }
214
215 /// Returns true if all bits are set.
216 bool all() const {
217 if (isSmall())
218 return getSmallBits() == (uintptr_t(1) << getSmallSize()) - 1;
219 return getPointer()->all();
220 }
221
222 /// Returns true if none of the bits are set.
223 bool none() const {
224 if (isSmall())
225 return getSmallBits() == 0;
226 return getPointer()->none();
227 }
228
229 /// Returns the index of the first set bit, -1 if none of the bits are set.
230 int find_first() const {
231 if (isSmall()) {
232 uintptr_t Bits = getSmallBits();
233 if (Bits == 0)
234 return -1;
235 return llvm::countr_zero(Bits);
236 }
237 return getPointer()->find_first();
238 }
239
240 int find_last() const {
241 if (isSmall()) {
242 uintptr_t Bits = getSmallBits();
243 if (Bits == 0)
244 return -1;
245 return NumBaseBits - llvm::countl_zero(Bits) - 1;
246 }
247 return getPointer()->find_last();
248 }
249
250 /// Returns the index of the first unset bit, -1 if all of the bits are set.
251 int find_first_unset() const {
252 if (isSmall()) {
253 if (count() == getSmallSize())
254 return -1;
255
256 uintptr_t Bits = getSmallBits();
257 return llvm::countr_one(Bits);
258 }
259 return getPointer()->find_first_unset();
260 }
261
262 int find_last_unset() const {
263 if (isSmall()) {
264 if (count() == getSmallSize())
265 return -1;
266
267 uintptr_t Bits = getSmallBits();
268 // Set unused bits.
269 Bits |= ~uintptr_t(0) << getSmallSize();
270 return NumBaseBits - llvm::countl_one(Bits) - 1;
271 }
272 return getPointer()->find_last_unset();
273 }
274
275 /// Returns the index of the next set bit following the "Prev" bit.
276 /// Returns -1 if the next set bit is not found.
277 int find_next(unsigned Prev) const {
278 if (isSmall()) {
279 uintptr_t Bits = getSmallBits();
280 // Mask off previous bits.
281 Bits &= ~uintptr_t(0) << (Prev + 1);
282 if (Bits == 0 || Prev + 1 >= getSmallSize())
283 return -1;
284 return llvm::countr_zero(Bits);
285 }
286 return getPointer()->find_next(Prev);
287 }
288
289 /// Returns the index of the next unset bit following the "Prev" bit.
290 /// Returns -1 if the next unset bit is not found.
291 int find_next_unset(unsigned Prev) const {
292 if (isSmall()) {
293 uintptr_t Bits = getSmallBits();
294 // Mask in previous bits.
295 Bits |= (uintptr_t(1) << (Prev + 1)) - 1;
296 // Mask in unused bits.
297 Bits |= ~uintptr_t(0) << getSmallSize();
298
299 if (Bits == ~uintptr_t(0) || Prev + 1 >= getSmallSize())
300 return -1;
301 return llvm::countr_one(Bits);
302 }
303 return getPointer()->find_next_unset(Prev);
304 }
305
306 /// find_prev - Returns the index of the first set bit that precedes the
307 /// the bit at \p PriorTo. Returns -1 if all previous bits are unset.
308 int find_prev(unsigned PriorTo) const {
309 if (isSmall()) {
310 if (PriorTo == 0)
311 return -1;
312
313 --PriorTo;
314 uintptr_t Bits = getSmallBits();
315 Bits &= maskTrailingOnes<uintptr_t>(PriorTo + 1);
316 if (Bits == 0)
317 return -1;
318
319 return NumBaseBits - llvm::countl_zero(Bits) - 1;
320 }
321 return getPointer()->find_prev(PriorTo);
322 }
323
324 /// Clear all bits.
325 void clear() {
326 if (!isSmall())
327 delete getPointer();
328 switchToSmall(0, 0);
329 }
330
331 /// Grow or shrink the bitvector.
332 void resize(unsigned N, bool t = false) {
333 if (!isSmall()) {
334 getPointer()->resize(N, t);
335 } else if (SmallNumDataBits >= N) {
336 uintptr_t NewBits = t ? ~uintptr_t(0) << getSmallSize() : 0;
337 setSmallSize(N);
338 setSmallBits(NewBits | getSmallBits());
339 } else {
340 BitVector *BV = new BitVector(N, t);
341 uintptr_t OldBits = getSmallBits();
342 for (size_type I = 0, E = getSmallSize(); I != E; ++I)
343 (*BV)[I] = (OldBits >> I) & 1;
344 switchToLarge(BV);
345 }
346 }
347
348 void reserve(unsigned N) {
349 if (isSmall()) {
350 if (N > SmallNumDataBits) {
351 uintptr_t OldBits = getSmallRawBits();
352 size_type SmallSize = getSmallSize();
353 BitVector *BV = new BitVector(SmallSize);
354 for (size_type I = 0; I < SmallSize; ++I)
355 if ((OldBits >> I) & 1)
356 BV->set(I);
357 BV->reserve(N);
358 switchToLarge(BV);
359 }
360 } else {
361 getPointer()->reserve(N);
362 }
363 }
364
365 // Set, reset, flip
366 SmallBitVector &set() {
367 if (isSmall())
368 setSmallBits(~uintptr_t(0));
369 else
370 getPointer()->set();
371 return *this;
372 }
373
374 SmallBitVector &set(unsigned Idx) {
375 if (isSmall()) {
376 assert(Idx <= static_cast<unsigned>((static_cast <bool> (Idx <= static_cast<unsigned>
( std::numeric_limits<uintptr_t>::digits) && "undefined behavior"
) ? void (0) : __assert_fail ("Idx <= static_cast<unsigned>( std::numeric_limits<uintptr_t>::digits) && \"undefined behavior\""
, "llvm/include/llvm/ADT/SmallBitVector.h", 378, __extension__
__PRETTY_FUNCTION__))
377 std::numeric_limits<uintptr_t>::digits) &&(static_cast <bool> (Idx <= static_cast<unsigned>
( std::numeric_limits<uintptr_t>::digits) && "undefined behavior"
) ? void (0) : __assert_fail ("Idx <= static_cast<unsigned>( std::numeric_limits<uintptr_t>::digits) && \"undefined behavior\""
, "llvm/include/llvm/ADT/SmallBitVector.h", 378, __extension__
__PRETTY_FUNCTION__))
378 "undefined behavior")(static_cast <bool> (Idx <= static_cast<unsigned>
( std::numeric_limits<uintptr_t>::digits) && "undefined behavior"
) ? void (0) : __assert_fail ("Idx <= static_cast<unsigned>( std::numeric_limits<uintptr_t>::digits) && \"undefined behavior\""
, "llvm/include/llvm/ADT/SmallBitVector.h", 378, __extension__
__PRETTY_FUNCTION__))
;
379 setSmallBits(getSmallBits() | (uintptr_t(1) << Idx));
380 }
381 else
382 getPointer()->set(Idx);
383 return *this;
384 }
385
386 /// Efficiently set a range of bits in [I, E)
387 SmallBitVector &set(unsigned I, unsigned E) {
388 assert(I <= E && "Attempted to set backwards range!")(static_cast <bool> (I <= E && "Attempted to set backwards range!"
) ? void (0) : __assert_fail ("I <= E && \"Attempted to set backwards range!\""
, "llvm/include/llvm/ADT/SmallBitVector.h", 388, __extension__
__PRETTY_FUNCTION__))
;
389 assert(E <= size() && "Attempted to set out-of-bounds range!")(static_cast <bool> (E <= size() && "Attempted to set out-of-bounds range!"
) ? void (0) : __assert_fail ("E <= size() && \"Attempted to set out-of-bounds range!\""
, "llvm/include/llvm/ADT/SmallBitVector.h", 389, __extension__
__PRETTY_FUNCTION__))
;
390 if (I == E) return *this;
391 if (isSmall()) {
392 uintptr_t EMask = ((uintptr_t)1) << E;
393 uintptr_t IMask = ((uintptr_t)1) << I;
394 uintptr_t Mask = EMask - IMask;
395 setSmallBits(getSmallBits() | Mask);
396 } else
397 getPointer()->set(I, E);
398 return *this;
399 }
400
401 SmallBitVector &reset() {
402 if (isSmall())
403 setSmallBits(0);
404 else
405 getPointer()->reset();
406 return *this;
407 }
408
409 SmallBitVector &reset(unsigned Idx) {
410 if (isSmall())
411 setSmallBits(getSmallBits() & ~(uintptr_t(1) << Idx));
412 else
413 getPointer()->reset(Idx);
414 return *this;
415 }
416
417 /// Efficiently reset a range of bits in [I, E)
418 SmallBitVector &reset(unsigned I, unsigned E) {
419 assert(I <= E && "Attempted to reset backwards range!")(static_cast <bool> (I <= E && "Attempted to reset backwards range!"
) ? void (0) : __assert_fail ("I <= E && \"Attempted to reset backwards range!\""
, "llvm/include/llvm/ADT/SmallBitVector.h", 419, __extension__
__PRETTY_FUNCTION__))
;
420 assert(E <= size() && "Attempted to reset out-of-bounds range!")(static_cast <bool> (E <= size() && "Attempted to reset out-of-bounds range!"
) ? void (0) : __assert_fail ("E <= size() && \"Attempted to reset out-of-bounds range!\""
, "llvm/include/llvm/ADT/SmallBitVector.h", 420, __extension__
__PRETTY_FUNCTION__))
;
421 if (I == E) return *this;
422 if (isSmall()) {
423 uintptr_t EMask = ((uintptr_t)1) << E;
424 uintptr_t IMask = ((uintptr_t)1) << I;
425 uintptr_t Mask = EMask - IMask;
426 setSmallBits(getSmallBits() & ~Mask);
427 } else
428 getPointer()->reset(I, E);
429 return *this;
430 }
431
432 SmallBitVector &flip() {
433 if (isSmall())
434 setSmallBits(~getSmallBits());
435 else
436 getPointer()->flip();
437 return *this;
438 }
439
440 SmallBitVector &flip(unsigned Idx) {
441 if (isSmall())
442 setSmallBits(getSmallBits() ^ (uintptr_t(1) << Idx));
443 else
444 getPointer()->flip(Idx);
445 return *this;
446 }
447
448 // No argument flip.
449 SmallBitVector operator~() const {
450 return SmallBitVector(*this).flip();
451 }
452
453 // Indexing.
454 reference operator[](unsigned Idx) {
455 assert(Idx < size() && "Out-of-bounds Bit access.")(static_cast <bool> (Idx < size() && "Out-of-bounds Bit access."
) ? void (0) : __assert_fail ("Idx < size() && \"Out-of-bounds Bit access.\""
, "llvm/include/llvm/ADT/SmallBitVector.h", 455, __extension__
__PRETTY_FUNCTION__))
;
456 return reference(*this, Idx);
457 }
458
459 bool operator[](unsigned Idx) const {
460 assert(Idx < size() && "Out-of-bounds Bit access.")(static_cast <bool> (Idx < size() && "Out-of-bounds Bit access."
) ? void (0) : __assert_fail ("Idx < size() && \"Out-of-bounds Bit access.\""
, "llvm/include/llvm/ADT/SmallBitVector.h", 460, __extension__
__PRETTY_FUNCTION__))
;
461 if (isSmall())
462 return ((getSmallBits() >> Idx) & 1) != 0;
463 return getPointer()->operator[](Idx);
464 }
465
466 /// Return the last element in the vector.
467 bool back() const {
468 assert(!empty() && "Getting last element of empty vector.")(static_cast <bool> (!empty() && "Getting last element of empty vector."
) ? void (0) : __assert_fail ("!empty() && \"Getting last element of empty vector.\""
, "llvm/include/llvm/ADT/SmallBitVector.h", 468, __extension__
__PRETTY_FUNCTION__))
;
469 return (*this)[size() - 1];
470 }
471
472 bool test(unsigned Idx) const {
473 return (*this)[Idx];
474 }
475
476 // Push single bit to end of vector.
477 void push_back(bool Val) {
478 resize(size() + 1, Val);
479 }
480
481 /// Pop one bit from the end of the vector.
482 void pop_back() {
483 assert(!empty() && "Empty vector has no element to pop.")(static_cast <bool> (!empty() && "Empty vector has no element to pop."
) ? void (0) : __assert_fail ("!empty() && \"Empty vector has no element to pop.\""
, "llvm/include/llvm/ADT/SmallBitVector.h", 483, __extension__
__PRETTY_FUNCTION__))
;
484 resize(size() - 1);
485 }
486
487 /// Test if any common bits are set.
488 bool anyCommon(const SmallBitVector &RHS) const {
489 if (isSmall() && RHS.isSmall())
490 return (getSmallBits() & RHS.getSmallBits()) != 0;
491 if (!isSmall() && !RHS.isSmall())
492 return getPointer()->anyCommon(*RHS.getPointer());
493
494 for (unsigned i = 0, e = std::min(size(), RHS.size()); i != e; ++i)
495 if (test(i) && RHS.test(i))
496 return true;
497 return false;
498 }
499
500 // Comparison operators.
501 bool operator==(const SmallBitVector &RHS) const {
502 if (size() != RHS.size())
503 return false;
504 if (isSmall() && RHS.isSmall())
505 return getSmallBits() == RHS.getSmallBits();
506 else if (!isSmall() && !RHS.isSmall())
507 return *getPointer() == *RHS.getPointer();
508 else {
509 for (size_type I = 0, E = size(); I != E; ++I) {
510 if ((*this)[I] != RHS[I])
511 return false;
512 }
513 return true;
514 }
515 }
516
517 bool operator!=(const SmallBitVector &RHS) const {
518 return !(*this == RHS);
519 }
520
521 // Intersection, union, disjoint union.
522 // FIXME BitVector::operator&= does not resize the LHS but this does
523 SmallBitVector &operator&=(const SmallBitVector &RHS) {
524 resize(std::max(size(), RHS.size()));
525 if (isSmall() && RHS.isSmall())
526 setSmallBits(getSmallBits() & RHS.getSmallBits());
527 else if (!isSmall() && !RHS.isSmall())
528 getPointer()->operator&=(*RHS.getPointer());
529 else {
530 size_type I, E;
531 for (I = 0, E = std::min(size(), RHS.size()); I != E; ++I)
532 (*this)[I] = test(I) && RHS.test(I);
533 for (E = size(); I != E; ++I)
534 reset(I);
535 }
536 return *this;
537 }
538
539 /// Reset bits that are set in RHS. Same as *this &= ~RHS.
540 SmallBitVector &reset(const SmallBitVector &RHS) {
541 if (isSmall() && RHS.isSmall())
542 setSmallBits(getSmallBits() & ~RHS.getSmallBits());
543 else if (!isSmall() && !RHS.isSmall())
544 getPointer()->reset(*RHS.getPointer());
545 else
546 for (unsigned i = 0, e = std::min(size(), RHS.size()); i != e; ++i)
547 if (RHS.test(i))
548 reset(i);
549
550 return *this;
551 }
552
553 /// Check if (This - RHS) is zero. This is the same as reset(RHS) and any().
554 bool test(const SmallBitVector &RHS) const {
555 if (isSmall() && RHS.isSmall())
556 return (getSmallBits() & ~RHS.getSmallBits()) != 0;
557 if (!isSmall() && !RHS.isSmall())
558 return getPointer()->test(*RHS.getPointer());
559
560 unsigned i, e;
561 for (i = 0, e = std::min(size(), RHS.size()); i != e; ++i)
562 if (test(i) && !RHS.test(i))
563 return true;
564
565 for (e = size(); i != e; ++i)
566 if (test(i))
567 return true;
568
569 return false;
570 }
571
572 SmallBitVector &operator|=(const SmallBitVector &RHS) {
573 resize(std::max(size(), RHS.size()));
574 if (isSmall() && RHS.isSmall())
575 setSmallBits(getSmallBits() | RHS.getSmallBits());
576 else if (!isSmall() && !RHS.isSmall())
577 getPointer()->operator|=(*RHS.getPointer());
578 else {
579 for (size_type I = 0, E = RHS.size(); I != E; ++I)
580 (*this)[I] = test(I) || RHS.test(I);
581 }
582 return *this;
583 }
584
585 SmallBitVector &operator^=(const SmallBitVector &RHS) {
586 resize(std::max(size(), RHS.size()));
587 if (isSmall() && RHS.isSmall())
588 setSmallBits(getSmallBits() ^ RHS.getSmallBits());
589 else if (!isSmall() && !RHS.isSmall())
590 getPointer()->operator^=(*RHS.getPointer());
591 else {
592 for (size_type I = 0, E = RHS.size(); I != E; ++I)
593 (*this)[I] = test(I) != RHS.test(I);
594 }
595 return *this;
596 }
597
598 SmallBitVector &operator<<=(unsigned N) {
599 if (isSmall())
600 setSmallBits(getSmallBits() << N);
601 else
602 getPointer()->operator<<=(N);
603 return *this;
604 }
605
606 SmallBitVector &operator>>=(unsigned N) {
607 if (isSmall())
608 setSmallBits(getSmallBits() >> N);
609 else
610 getPointer()->operator>>=(N);
611 return *this;
612 }
613
614 // Assignment operator.
615 const SmallBitVector &operator=(const SmallBitVector &RHS) {
616 if (isSmall()) {
617 if (RHS.isSmall())
618 X = RHS.X;
619 else
620 switchToLarge(new BitVector(*RHS.getPointer()));
621 } else {
622 if (!RHS.isSmall())
623 *getPointer() = *RHS.getPointer();
624 else {
625 delete getPointer();
626 X = RHS.X;
627 }
628 }
629 return *this;
630 }
631
632 const SmallBitVector &operator=(SmallBitVector &&RHS) {
633 if (this != &RHS) {
634 clear();
635 swap(RHS);
636 }
637 return *this;
638 }
639
640 void swap(SmallBitVector &RHS) {
641 std::swap(X, RHS.X);
642 }
643
644 /// Add '1' bits from Mask to this vector. Don't resize.
645 /// This computes "*this |= Mask".
646 void setBitsInMask(const uint32_t *Mask, unsigned MaskWords = ~0u) {
647 if (isSmall())
648 applyMask<true, false>(Mask, MaskWords);
649 else
650 getPointer()->setBitsInMask(Mask, MaskWords);
651 }
652
653 /// Clear any bits in this vector that are set in Mask. Don't resize.
654 /// This computes "*this &= ~Mask".
655 void clearBitsInMask(const uint32_t *Mask, unsigned MaskWords = ~0u) {
656 if (isSmall())
657 applyMask<false, false>(Mask, MaskWords);
658 else
659 getPointer()->clearBitsInMask(Mask, MaskWords);
660 }
661
662 /// Add a bit to this vector for every '0' bit in Mask. Don't resize.
663 /// This computes "*this |= ~Mask".
664 void setBitsNotInMask(const uint32_t *Mask, unsigned MaskWords = ~0u) {
665 if (isSmall())
666 applyMask<true, true>(Mask, MaskWords);
667 else
668 getPointer()->setBitsNotInMask(Mask, MaskWords);
669 }
670
671 /// Clear a bit in this vector for every '0' bit in Mask. Don't resize.
672 /// This computes "*this &= Mask".
673 void clearBitsNotInMask(const uint32_t *Mask, unsigned MaskWords = ~0u) {
674 if (isSmall())
675 applyMask<false, true>(Mask, MaskWords);
676 else
677 getPointer()->clearBitsNotInMask(Mask, MaskWords);
678 }
679
680 void invalid() {
681 assert(empty())(static_cast <bool> (empty()) ? void (0) : __assert_fail
("empty()", "llvm/include/llvm/ADT/SmallBitVector.h", 681, __extension__
__PRETTY_FUNCTION__))
;
682 X = (uintptr_t)-1;
683 }
684 bool isInvalid() const { return X == (uintptr_t)-1; }
685
686 ArrayRef<uintptr_t> getData(uintptr_t &Store) const {
687 if (!isSmall())
688 return getPointer()->getData();
689 Store = getSmallBits();
690 return Store;
691 }
692
693private:
694 template <bool AddBits, bool InvertMask>
695 void applyMask(const uint32_t *Mask, unsigned MaskWords) {
696 assert(MaskWords <= sizeof(uintptr_t) && "Mask is larger than base!")(static_cast <bool> (MaskWords <= sizeof(uintptr_t) &&
"Mask is larger than base!") ? void (0) : __assert_fail ("MaskWords <= sizeof(uintptr_t) && \"Mask is larger than base!\""
, "llvm/include/llvm/ADT/SmallBitVector.h", 696, __extension__
__PRETTY_FUNCTION__))
;
697 uintptr_t M = Mask[0];
698 if (NumBaseBits == 64)
699 M |= uint64_t(Mask[1]) << 32;
700 if (InvertMask)
701 M = ~M;
702 if (AddBits)
703 setSmallBits(getSmallBits() | M);
704 else
705 setSmallBits(getSmallBits() & ~M);
706 }
707};
708
709inline SmallBitVector
710operator&(const SmallBitVector &LHS, const SmallBitVector &RHS) {
711 SmallBitVector Result(LHS);
712 Result &= RHS;
713 return Result;
714}
715
716inline SmallBitVector
717operator|(const SmallBitVector &LHS, const SmallBitVector &RHS) {
718 SmallBitVector Result(LHS);
719 Result |= RHS;
720 return Result;
721}
722
723inline SmallBitVector
724operator^(const SmallBitVector &LHS, const SmallBitVector &RHS) {
725 SmallBitVector Result(LHS);
726 Result ^= RHS;
727 return Result;
728}
729
730template <> struct DenseMapInfo<SmallBitVector> {
731 static inline SmallBitVector getEmptyKey() { return SmallBitVector(); }
732 static inline SmallBitVector getTombstoneKey() {
733 SmallBitVector V;
734 V.invalid();
735 return V;
736 }
737 static unsigned getHashValue(const SmallBitVector &V) {
738 uintptr_t Store;
739 return DenseMapInfo<
740 std::pair<SmallBitVector::size_type, ArrayRef<uintptr_t>>>::
741 getHashValue(std::make_pair(V.size(), V.getData(Store)));
742 }
743 static bool isEqual(const SmallBitVector &LHS, const SmallBitVector &RHS) {
744 if (LHS.isInvalid() || RHS.isInvalid())
745 return LHS.isInvalid() == RHS.isInvalid();
746 return LHS == RHS;
747 }
748};
749} // end namespace llvm
750
751namespace std {
752
753/// Implement std::swap in terms of BitVector swap.
754inline void
755swap(llvm::SmallBitVector &LHS, llvm::SmallBitVector &RHS) {
756 LHS.swap(RHS);
757}
758
759} // end namespace std
760
761#endif // LLVM_ADT_SMALLBITVECTOR_H