Bug Summary

File:llvm/include/llvm/ADT/SmallBitVector.h
Warning:line 96, 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-store=region -analyzer-opt-analyze-nested-blocks -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/llvm-toolchain-snapshot-14~++20220125101009+ceec4383681c/build-llvm/tools/clang/stage2-bins -resource-dir /usr/lib/llvm-14/lib/clang/14.0.0 -isystem /usr/include/libxml2 -D HAVE_ROUND -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I tools/lldb/source/Core -I /build/llvm-toolchain-snapshot-14~++20220125101009+ceec4383681c/lldb/source/Core -I /build/llvm-toolchain-snapshot-14~++20220125101009+ceec4383681c/lldb/include -I tools/lldb/include -I include -I /build/llvm-toolchain-snapshot-14~++20220125101009+ceec4383681c/llvm/include -I /usr/include/python3.9 -I /build/llvm-toolchain-snapshot-14~++20220125101009+ceec4383681c/clang/include -I tools/lldb/../clang/include -I /build/llvm-toolchain-snapshot-14~++20220125101009+ceec4383681c/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-14/lib/clang/14.0.0/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/llvm-toolchain-snapshot-14~++20220125101009+ceec4383681c/build-llvm/tools/clang/stage2-bins=build-llvm/tools/clang/stage2-bins -fmacro-prefix-map=/build/llvm-toolchain-snapshot-14~++20220125101009+ceec4383681c/= -fcoverage-prefix-map=/build/llvm-toolchain-snapshot-14~++20220125101009+ceec4383681c/build-llvm/tools/clang/stage2-bins=build-llvm/tools/clang/stage2-bins -fcoverage-prefix-map=/build/llvm-toolchain-snapshot-14~++20220125101009+ceec4383681c/= -O3 -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-deprecated-declarations -Wno-unknown-pragmas -Wno-strict-aliasing -Wno-deprecated-register -Wno-vla-extension -std=c++14 -fdeprecated-macro -fdebug-compilation-dir=/build/llvm-toolchain-snapshot-14~++20220125101009+ceec4383681c/build-llvm/tools/clang/stage2-bins -fdebug-prefix-map=/build/llvm-toolchain-snapshot-14~++20220125101009+ceec4383681c/build-llvm/tools/clang/stage2-bins=build-llvm/tools/clang/stage2-bins -fdebug-prefix-map=/build/llvm-toolchain-snapshot-14~++20220125101009+ceec4383681c/= -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-2022-01-25-232935-20746-1 -x c++ /build/llvm-toolchain-snapshot-14~++20220125101009+ceec4383681c/lldb/source/Core/PluginManager.cpp

/build/llvm-toolchain-snapshot-14~++20220125101009+ceec4383681c/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 : PluginInstance<ObjectFileCreateInstance>(name, description,
626 create_callback),
627 create_memory_callback(create_memory_callback),
628 get_module_specifications(get_module_specifications),
629 save_core(save_core) {}
630
631 ObjectFileCreateMemoryInstance create_memory_callback;
632 ObjectFileGetModuleSpecifications get_module_specifications;
633 ObjectFileSaveCore save_core;
634};
635typedef PluginInstances<ObjectFileInstance> ObjectFileInstances;
636
637static ObjectFileInstances &GetObjectFileInstances() {
638 static ObjectFileInstances g_instances;
639 return g_instances;
640}
641
642bool PluginManager::RegisterPlugin(
643 llvm::StringRef name, llvm::StringRef description,
644 ObjectFileCreateInstance create_callback,
645 ObjectFileCreateMemoryInstance create_memory_callback,
646 ObjectFileGetModuleSpecifications get_module_specifications,
647 ObjectFileSaveCore save_core) {
648 return GetObjectFileInstances().RegisterPlugin(
649 name, description, create_callback, create_memory_callback,
650 get_module_specifications, save_core);
651}
652
653bool PluginManager::UnregisterPlugin(ObjectFileCreateInstance create_callback) {
654 return GetObjectFileInstances().UnregisterPlugin(create_callback);
655}
656
657ObjectFileCreateInstance
658PluginManager::GetObjectFileCreateCallbackAtIndex(uint32_t idx) {
659 return GetObjectFileInstances().GetCallbackAtIndex(idx);
660}
661
662ObjectFileCreateMemoryInstance
663PluginManager::GetObjectFileCreateMemoryCallbackAtIndex(uint32_t idx) {
664 const auto &instances = GetObjectFileInstances().GetInstances();
665 if (idx < instances.size())
666 return instances[idx].create_memory_callback;
667 return nullptr;
668}
669
670ObjectFileGetModuleSpecifications
671PluginManager::GetObjectFileGetModuleSpecificationsCallbackAtIndex(
672 uint32_t idx) {
673 const auto &instances = GetObjectFileInstances().GetInstances();
674 if (idx < instances.size())
675 return instances[idx].get_module_specifications;
676 return nullptr;
677}
678
679ObjectFileCreateMemoryInstance
680PluginManager::GetObjectFileCreateMemoryCallbackForPluginName(
681 llvm::StringRef name) {
682 const auto &instances = GetObjectFileInstances().GetInstances();
683 for (auto &instance : instances) {
684 if (instance.name == name)
685 return instance.create_memory_callback;
686 }
687 return nullptr;
688}
689
690Status PluginManager::SaveCore(const lldb::ProcessSP &process_sp,
691 const FileSpec &outfile,
692 lldb::SaveCoreStyle &core_style,
693 llvm::StringRef plugin_name) {
694 if (plugin_name.empty()) {
695 // Try saving core directly from the process plugin first.
696 llvm::Expected<bool> ret = process_sp->SaveCore(outfile.GetPath());
697 if (!ret)
698 return Status(ret.takeError());
699 if (ret.get())
700 return Status();
701 }
702
703 // Fall back to object plugins.
704 Status error;
705 auto &instances = GetObjectFileInstances().GetInstances();
706 for (auto &instance : instances) {
707 if (plugin_name.empty() || instance.name == plugin_name) {
708 if (instance.save_core &&
709 instance.save_core(process_sp, outfile, core_style, error))
710 return error;
711 }
712 }
713 error.SetErrorString(
714 "no ObjectFile plugins were able to save a core for this process");
715 return error;
716}
717
718#pragma mark ObjectContainer
719
720struct ObjectContainerInstance
721 : public PluginInstance<ObjectContainerCreateInstance> {
722 ObjectContainerInstance(
723 llvm::StringRef name, llvm::StringRef description,
724 CallbackType create_callback,
725 ObjectFileGetModuleSpecifications get_module_specifications)
726 : PluginInstance<ObjectContainerCreateInstance>(name, description,
727 create_callback),
728 get_module_specifications(get_module_specifications) {}
729
730 ObjectFileGetModuleSpecifications get_module_specifications;
731};
732typedef PluginInstances<ObjectContainerInstance> ObjectContainerInstances;
733
734static ObjectContainerInstances &GetObjectContainerInstances() {
735 static ObjectContainerInstances g_instances;
736 return g_instances;
737}
738
739bool PluginManager::RegisterPlugin(
740 llvm::StringRef name, llvm::StringRef description,
741 ObjectContainerCreateInstance create_callback,
742 ObjectFileGetModuleSpecifications get_module_specifications) {
743 return GetObjectContainerInstances().RegisterPlugin(
744 name, description, create_callback, get_module_specifications);
745}
746
747bool PluginManager::UnregisterPlugin(
748 ObjectContainerCreateInstance create_callback) {
749 return GetObjectContainerInstances().UnregisterPlugin(create_callback);
750}
751
752ObjectContainerCreateInstance
753PluginManager::GetObjectContainerCreateCallbackAtIndex(uint32_t idx) {
754 return GetObjectContainerInstances().GetCallbackAtIndex(idx);
755}
756
757ObjectFileGetModuleSpecifications
758PluginManager::GetObjectContainerGetModuleSpecificationsCallbackAtIndex(
759 uint32_t idx) {
760 const auto &instances = GetObjectContainerInstances().GetInstances();
761 if (idx < instances.size())
762 return instances[idx].get_module_specifications;
763 return nullptr;
764}
765
766#pragma mark Platform
767
768typedef PluginInstance<PlatformCreateInstance> PlatformInstance;
769typedef PluginInstances<PlatformInstance> PlatformInstances;
770
771static PlatformInstances &GetPlatformInstances() {
772 static PlatformInstances g_platform_instances;
773 return g_platform_instances;
774}
775
776bool PluginManager::RegisterPlugin(
777 llvm::StringRef name, llvm::StringRef description,
778 PlatformCreateInstance create_callback,
779 DebuggerInitializeCallback debugger_init_callback) {
780 return GetPlatformInstances().RegisterPlugin(
781 name, description, create_callback, debugger_init_callback);
782}
783
784bool PluginManager::UnregisterPlugin(PlatformCreateInstance create_callback) {
785 return GetPlatformInstances().UnregisterPlugin(create_callback);
786}
787
788llvm::StringRef PluginManager::GetPlatformPluginNameAtIndex(uint32_t idx) {
789 return GetPlatformInstances().GetNameAtIndex(idx);
790}
791
792llvm::StringRef
793PluginManager::GetPlatformPluginDescriptionAtIndex(uint32_t idx) {
794 return GetPlatformInstances().GetDescriptionAtIndex(idx);
795}
796
797PlatformCreateInstance
798PluginManager::GetPlatformCreateCallbackAtIndex(uint32_t idx) {
799 return GetPlatformInstances().GetCallbackAtIndex(idx);
800}
801
802PlatformCreateInstance
803PluginManager::GetPlatformCreateCallbackForPluginName(llvm::StringRef name) {
804 return GetPlatformInstances().GetCallbackForName(name);
805}
806
807void PluginManager::AutoCompletePlatformName(llvm::StringRef name,
808 CompletionRequest &request) {
809 for (const auto &instance : GetPlatformInstances().GetInstances()) {
810 if (instance.name.startswith(name))
811 request.AddCompletion(instance.name);
812 }
813}
814
815#pragma mark Process
816
817typedef PluginInstance<ProcessCreateInstance> ProcessInstance;
818typedef PluginInstances<ProcessInstance> ProcessInstances;
819
820static ProcessInstances &GetProcessInstances() {
821 static ProcessInstances g_instances;
822 return g_instances;
823}
824
825bool PluginManager::RegisterPlugin(
826 llvm::StringRef name, llvm::StringRef description,
827 ProcessCreateInstance create_callback,
828 DebuggerInitializeCallback debugger_init_callback) {
829 return GetProcessInstances().RegisterPlugin(
830 name, description, create_callback, debugger_init_callback);
831}
832
833bool PluginManager::UnregisterPlugin(ProcessCreateInstance create_callback) {
834 return GetProcessInstances().UnregisterPlugin(create_callback);
835}
836
837llvm::StringRef PluginManager::GetProcessPluginNameAtIndex(uint32_t idx) {
838 return GetProcessInstances().GetNameAtIndex(idx);
839}
840
841llvm::StringRef PluginManager::GetProcessPluginDescriptionAtIndex(uint32_t idx) {
842 return GetProcessInstances().GetDescriptionAtIndex(idx);
843}
844
845ProcessCreateInstance
846PluginManager::GetProcessCreateCallbackAtIndex(uint32_t idx) {
847 return GetProcessInstances().GetCallbackAtIndex(idx);
848}
849
850ProcessCreateInstance
851PluginManager::GetProcessCreateCallbackForPluginName(llvm::StringRef name) {
852 return GetProcessInstances().GetCallbackForName(name);
853}
854
855void PluginManager::AutoCompleteProcessName(llvm::StringRef name,
856 CompletionRequest &request) {
857 for (const auto &instance : GetProcessInstances().GetInstances()) {
858 if (instance.name.startswith(name))
859 request.AddCompletion(instance.name, instance.description);
860 }
861}
862
863#pragma mark ScriptInterpreter
864
865struct ScriptInterpreterInstance
866 : public PluginInstance<ScriptInterpreterCreateInstance> {
867 ScriptInterpreterInstance(llvm::StringRef name, llvm::StringRef description,
868 CallbackType create_callback,
869 lldb::ScriptLanguage language)
870 : PluginInstance<ScriptInterpreterCreateInstance>(name, description,
871 create_callback),
872 language(language) {}
873
874 lldb::ScriptLanguage language = lldb::eScriptLanguageNone;
875};
876
877typedef PluginInstances<ScriptInterpreterInstance> ScriptInterpreterInstances;
878
879static ScriptInterpreterInstances &GetScriptInterpreterInstances() {
880 static ScriptInterpreterInstances g_instances;
881 return g_instances;
882}
883
884bool PluginManager::RegisterPlugin(
885 llvm::StringRef name, llvm::StringRef description,
886 lldb::ScriptLanguage script_language,
887 ScriptInterpreterCreateInstance create_callback) {
888 return GetScriptInterpreterInstances().RegisterPlugin(
889 name, description, create_callback, script_language);
890}
891
892bool PluginManager::UnregisterPlugin(
893 ScriptInterpreterCreateInstance create_callback) {
894 return GetScriptInterpreterInstances().UnregisterPlugin(create_callback);
895}
896
897ScriptInterpreterCreateInstance
898PluginManager::GetScriptInterpreterCreateCallbackAtIndex(uint32_t idx) {
899 return GetScriptInterpreterInstances().GetCallbackAtIndex(idx);
900}
901
902lldb::ScriptInterpreterSP
903PluginManager::GetScriptInterpreterForLanguage(lldb::ScriptLanguage script_lang,
904 Debugger &debugger) {
905 const auto &instances = GetScriptInterpreterInstances().GetInstances();
906 ScriptInterpreterCreateInstance none_instance = nullptr;
907 for (const auto &instance : instances) {
908 if (instance.language == lldb::eScriptLanguageNone)
909 none_instance = instance.create_callback;
910
911 if (script_lang == instance.language)
912 return instance.create_callback(debugger);
913 }
914
915 // If we didn't find one, return the ScriptInterpreter for the null language.
916 assert(none_instance != nullptr)(static_cast <bool> (none_instance != nullptr) ? void (
0) : __assert_fail ("none_instance != nullptr", "lldb/source/Core/PluginManager.cpp"
, 916, __extension__ __PRETTY_FUNCTION__))
;
917 return none_instance(debugger);
918}
919
920#pragma mark StructuredDataPlugin
921
922struct StructuredDataPluginInstance
923 : public PluginInstance<StructuredDataPluginCreateInstance> {
924 StructuredDataPluginInstance(
925 llvm::StringRef name, llvm::StringRef description,
926 CallbackType create_callback,
927 DebuggerInitializeCallback debugger_init_callback,
928 StructuredDataFilterLaunchInfo filter_callback)
929 : PluginInstance<StructuredDataPluginCreateInstance>(
930 name, description, create_callback, debugger_init_callback),
931 filter_callback(filter_callback) {}
932
933 StructuredDataFilterLaunchInfo filter_callback = nullptr;
934};
935
936typedef PluginInstances<StructuredDataPluginInstance>
937 StructuredDataPluginInstances;
938
939static StructuredDataPluginInstances &GetStructuredDataPluginInstances() {
940 static StructuredDataPluginInstances g_instances;
941 return g_instances;
942}
943
944bool PluginManager::RegisterPlugin(
945 llvm::StringRef name, llvm::StringRef description,
946 StructuredDataPluginCreateInstance create_callback,
947 DebuggerInitializeCallback debugger_init_callback,
948 StructuredDataFilterLaunchInfo filter_callback) {
949 return GetStructuredDataPluginInstances().RegisterPlugin(
950 name, description, create_callback, debugger_init_callback,
951 filter_callback);
952}
953
954bool PluginManager::UnregisterPlugin(
955 StructuredDataPluginCreateInstance create_callback) {
956 return GetStructuredDataPluginInstances().UnregisterPlugin(create_callback);
957}
958
959StructuredDataPluginCreateInstance
960PluginManager::GetStructuredDataPluginCreateCallbackAtIndex(uint32_t idx) {
961 return GetStructuredDataPluginInstances().GetCallbackAtIndex(idx);
962}
963
964StructuredDataFilterLaunchInfo
965PluginManager::GetStructuredDataFilterCallbackAtIndex(
966 uint32_t idx, bool &iteration_complete) {
967 const auto &instances = GetStructuredDataPluginInstances().GetInstances();
968 if (idx < instances.size()) {
969 iteration_complete = false;
970 return instances[idx].filter_callback;
971 } else {
972 iteration_complete = true;
973 }
974 return nullptr;
975}
976
977#pragma mark SymbolFile
978
979typedef PluginInstance<SymbolFileCreateInstance> SymbolFileInstance;
980typedef PluginInstances<SymbolFileInstance> SymbolFileInstances;
981
982static SymbolFileInstances &GetSymbolFileInstances() {
983 static SymbolFileInstances g_instances;
984 return g_instances;
985}
986
987bool PluginManager::RegisterPlugin(
988 llvm::StringRef name, llvm::StringRef description,
989 SymbolFileCreateInstance create_callback,
990 DebuggerInitializeCallback debugger_init_callback) {
991 return GetSymbolFileInstances().RegisterPlugin(
992 name, description, create_callback, debugger_init_callback);
993}
994
995bool PluginManager::UnregisterPlugin(SymbolFileCreateInstance create_callback) {
996 return GetSymbolFileInstances().UnregisterPlugin(create_callback);
997}
998
999SymbolFileCreateInstance
1000PluginManager::GetSymbolFileCreateCallbackAtIndex(uint32_t idx) {
1001 return GetSymbolFileInstances().GetCallbackAtIndex(idx);
1002}
1003
1004#pragma mark SymbolVendor
1005
1006typedef PluginInstance<SymbolVendorCreateInstance> SymbolVendorInstance;
1007typedef PluginInstances<SymbolVendorInstance> SymbolVendorInstances;
1008
1009static SymbolVendorInstances &GetSymbolVendorInstances() {
1010 static SymbolVendorInstances g_instances;
1011 return g_instances;
1012}
1013
1014bool PluginManager::RegisterPlugin(llvm::StringRef name,
1015 llvm::StringRef description,
1016 SymbolVendorCreateInstance create_callback) {
1017 return GetSymbolVendorInstances().RegisterPlugin(name, description,
1018 create_callback);
1019}
1020
1021bool PluginManager::UnregisterPlugin(
1022 SymbolVendorCreateInstance create_callback) {
1023 return GetSymbolVendorInstances().UnregisterPlugin(create_callback);
1024}
1025
1026SymbolVendorCreateInstance
1027PluginManager::GetSymbolVendorCreateCallbackAtIndex(uint32_t idx) {
1028 return GetSymbolVendorInstances().GetCallbackAtIndex(idx);
1029}
1030
1031#pragma mark Trace
1032
1033struct TraceInstance
1034 : public PluginInstance<TraceCreateInstanceForSessionFile> {
1035 TraceInstance(
1036 llvm::StringRef name, llvm::StringRef description,
1037 CallbackType create_callback_for_session_file,
1038 TraceCreateInstanceForLiveProcess create_callback_for_live_process,
1039 llvm::StringRef schema)
1040 : PluginInstance<TraceCreateInstanceForSessionFile>(
1041 name, description, create_callback_for_session_file),
1042 schema(schema),
1043 create_callback_for_live_process(create_callback_for_live_process) {}
1044
1045 llvm::StringRef schema;
1046 TraceCreateInstanceForLiveProcess create_callback_for_live_process;
1047};
1048
1049typedef PluginInstances<TraceInstance> TraceInstances;
1050
1051static TraceInstances &GetTracePluginInstances() {
1052 static TraceInstances g_instances;
1053 return g_instances;
1054}
1055
1056bool PluginManager::RegisterPlugin(
1057 llvm::StringRef name, llvm::StringRef description,
1058 TraceCreateInstanceForSessionFile create_callback_for_session_file,
1059 TraceCreateInstanceForLiveProcess create_callback_for_live_process,
1060 llvm::StringRef schema) {
1061 return GetTracePluginInstances().RegisterPlugin(
1062 name, description, create_callback_for_session_file,
1063 create_callback_for_live_process, schema);
1064}
1065
1066bool PluginManager::UnregisterPlugin(
1067 TraceCreateInstanceForSessionFile create_callback_for_session_file) {
1068 return GetTracePluginInstances().UnregisterPlugin(
1069 create_callback_for_session_file);
1070}
1071
1072TraceCreateInstanceForSessionFile
1073PluginManager::GetTraceCreateCallback(llvm::StringRef plugin_name) {
1074 return GetTracePluginInstances().GetCallbackForName(plugin_name);
1075}
1076
1077TraceCreateInstanceForLiveProcess
1078PluginManager::GetTraceCreateCallbackForLiveProcess(llvm::StringRef plugin_name) {
1079 for (const TraceInstance &instance : GetTracePluginInstances().GetInstances())
1080 if (instance.name == plugin_name)
1081 return instance.create_callback_for_live_process;
1082 return nullptr;
1083}
1084
1085llvm::StringRef PluginManager::GetTraceSchema(llvm::StringRef plugin_name) {
1086 for (const TraceInstance &instance : GetTracePluginInstances().GetInstances())
1087 if (instance.name == plugin_name)
1088 return instance.schema;
1089 return llvm::StringRef();
1090}
1091
1092llvm::StringRef PluginManager::GetTraceSchema(size_t index) {
1093 if (TraceInstance *instance =
1094 GetTracePluginInstances().GetInstanceAtIndex(index))
1095 return instance->schema;
1096 return llvm::StringRef();
1097}
1098
1099#pragma mark TraceExporter
1100
1101struct TraceExporterInstance
1102 : public PluginInstance<TraceExporterCreateInstance> {
1103 TraceExporterInstance(
1104 llvm::StringRef name, llvm::StringRef description,
1105 TraceExporterCreateInstance create_instance,
1106 ThreadTraceExportCommandCreator create_thread_trace_export_command)
1107 : PluginInstance<TraceExporterCreateInstance>(name, description,
1108 create_instance),
1109 create_thread_trace_export_command(create_thread_trace_export_command) {
1110 }
1111
1112 ThreadTraceExportCommandCreator create_thread_trace_export_command;
1113};
1114
1115typedef PluginInstances<TraceExporterInstance> TraceExporterInstances;
1116
1117static TraceExporterInstances &GetTraceExporterInstances() {
1118 static TraceExporterInstances g_instances;
1119 return g_instances;
1120}
1121
1122bool PluginManager::RegisterPlugin(
1123 llvm::StringRef name, llvm::StringRef description,
1124 TraceExporterCreateInstance create_callback,
1125 ThreadTraceExportCommandCreator create_thread_trace_export_command) {
1126 return GetTraceExporterInstances().RegisterPlugin(
1127 name, description, create_callback, create_thread_trace_export_command);
1128}
1129
1130TraceExporterCreateInstance
1131PluginManager::GetTraceExporterCreateCallback(llvm::StringRef plugin_name) {
1132 return GetTraceExporterInstances().GetCallbackForName(plugin_name);
1133}
1134
1135bool PluginManager::UnregisterPlugin(
1136 TraceExporterCreateInstance create_callback) {
1137 return GetTraceExporterInstances().UnregisterPlugin(create_callback);
1138}
1139
1140ThreadTraceExportCommandCreator
1141PluginManager::GetThreadTraceExportCommandCreatorAtIndex(uint32_t index) {
1142 if (TraceExporterInstance *instance =
1143 GetTraceExporterInstances().GetInstanceAtIndex(index))
1144 return instance->create_thread_trace_export_command;
1145 return nullptr;
1146}
1147
1148llvm::StringRef
1149PluginManager::GetTraceExporterPluginNameAtIndex(uint32_t index) {
1150 return GetTraceExporterInstances().GetNameAtIndex(index);
1151}
1152
1153#pragma mark UnwindAssembly
1154
1155typedef PluginInstance<UnwindAssemblyCreateInstance> UnwindAssemblyInstance;
1156typedef PluginInstances<UnwindAssemblyInstance> UnwindAssemblyInstances;
1157
1158static UnwindAssemblyInstances &GetUnwindAssemblyInstances() {
1159 static UnwindAssemblyInstances g_instances;
1160 return g_instances;
1161}
1162
1163bool PluginManager::RegisterPlugin(
1164 llvm::StringRef name, llvm::StringRef description,
1165 UnwindAssemblyCreateInstance create_callback) {
1166 return GetUnwindAssemblyInstances().RegisterPlugin(name, description,
1167 create_callback);
1168}
1169
1170bool PluginManager::UnregisterPlugin(
1171 UnwindAssemblyCreateInstance create_callback) {
1172 return GetUnwindAssemblyInstances().UnregisterPlugin(create_callback);
1173}
1174
1175UnwindAssemblyCreateInstance
1176PluginManager::GetUnwindAssemblyCreateCallbackAtIndex(uint32_t idx) {
1177 return GetUnwindAssemblyInstances().GetCallbackAtIndex(idx);
1178}
1179
1180#pragma mark MemoryHistory
1181
1182typedef PluginInstance<MemoryHistoryCreateInstance> MemoryHistoryInstance;
1183typedef PluginInstances<MemoryHistoryInstance> MemoryHistoryInstances;
1184
1185static MemoryHistoryInstances &GetMemoryHistoryInstances() {
1186 static MemoryHistoryInstances g_instances;
1187 return g_instances;
1188}
1189
1190bool PluginManager::RegisterPlugin(
1191 llvm::StringRef name, llvm::StringRef description,
1192 MemoryHistoryCreateInstance create_callback) {
1193 return GetMemoryHistoryInstances().RegisterPlugin(name, description,
1194 create_callback);
1195}
1196
1197bool PluginManager::UnregisterPlugin(
1198 MemoryHistoryCreateInstance create_callback) {
1199 return GetMemoryHistoryInstances().UnregisterPlugin(create_callback);
1200}
1201
1202MemoryHistoryCreateInstance
1203PluginManager::GetMemoryHistoryCreateCallbackAtIndex(uint32_t idx) {
1204 return GetMemoryHistoryInstances().GetCallbackAtIndex(idx);
1205}
1206
1207#pragma mark InstrumentationRuntime
1208
1209struct InstrumentationRuntimeInstance
1210 : public PluginInstance<InstrumentationRuntimeCreateInstance> {
1211 InstrumentationRuntimeInstance(
1212 llvm::StringRef name, llvm::StringRef description,
1213 CallbackType create_callback,
1214 InstrumentationRuntimeGetType get_type_callback)
1215 : PluginInstance<InstrumentationRuntimeCreateInstance>(name, description,
1216 create_callback),
1217 get_type_callback(get_type_callback) {}
1218
1219 InstrumentationRuntimeGetType get_type_callback = nullptr;
1220};
1221
1222typedef PluginInstances<InstrumentationRuntimeInstance>
1223 InstrumentationRuntimeInstances;
1224
1225static InstrumentationRuntimeInstances &GetInstrumentationRuntimeInstances() {
1226 static InstrumentationRuntimeInstances g_instances;
1227 return g_instances;
1228}
1229
1230bool PluginManager::RegisterPlugin(
1231 llvm::StringRef name, llvm::StringRef description,
1232 InstrumentationRuntimeCreateInstance create_callback,
1233 InstrumentationRuntimeGetType get_type_callback) {
1234 return GetInstrumentationRuntimeInstances().RegisterPlugin(
1235 name, description, create_callback, get_type_callback);
1236}
1237
1238bool PluginManager::UnregisterPlugin(
1239 InstrumentationRuntimeCreateInstance create_callback) {
1240 return GetInstrumentationRuntimeInstances().UnregisterPlugin(create_callback);
1241}
1242
1243InstrumentationRuntimeGetType
1244PluginManager::GetInstrumentationRuntimeGetTypeCallbackAtIndex(uint32_t idx) {
1245 const auto &instances = GetInstrumentationRuntimeInstances().GetInstances();
1246 if (idx < instances.size())
1247 return instances[idx].get_type_callback;
1248 return nullptr;
1249}
1250
1251InstrumentationRuntimeCreateInstance
1252PluginManager::GetInstrumentationRuntimeCreateCallbackAtIndex(uint32_t idx) {
1253 return GetInstrumentationRuntimeInstances().GetCallbackAtIndex(idx);
1254}
1255
1256#pragma mark TypeSystem
1257
1258struct TypeSystemInstance : public PluginInstance<TypeSystemCreateInstance> {
1259 TypeSystemInstance(llvm::StringRef name, llvm::StringRef description,
1260 CallbackType create_callback,
1261 LanguageSet supported_languages_for_types,
1262 LanguageSet supported_languages_for_expressions)
1263 : PluginInstance<TypeSystemCreateInstance>(name, description,
1264 create_callback),
1265 supported_languages_for_types(supported_languages_for_types),
1266 supported_languages_for_expressions(
1267 supported_languages_for_expressions) {}
1268
1269 LanguageSet supported_languages_for_types;
1270 LanguageSet supported_languages_for_expressions;
1271};
1272
1273typedef PluginInstances<TypeSystemInstance> TypeSystemInstances;
1274
1275static TypeSystemInstances &GetTypeSystemInstances() {
1276 static TypeSystemInstances g_instances;
1277 return g_instances;
1278}
1279
1280bool PluginManager::RegisterPlugin(
1281 llvm::StringRef name, llvm::StringRef description,
1282 TypeSystemCreateInstance create_callback,
1283 LanguageSet supported_languages_for_types,
1284 LanguageSet supported_languages_for_expressions) {
1285 return GetTypeSystemInstances().RegisterPlugin(
1
Calling 'PluginInstances::RegisterPlugin'
1286 name, description, create_callback, supported_languages_for_types,
1287 supported_languages_for_expressions);
1288}
1289
1290bool PluginManager::UnregisterPlugin(TypeSystemCreateInstance create_callback) {
1291 return GetTypeSystemInstances().UnregisterPlugin(create_callback);
1292}
1293
1294TypeSystemCreateInstance
1295PluginManager::GetTypeSystemCreateCallbackAtIndex(uint32_t idx) {
1296 return GetTypeSystemInstances().GetCallbackAtIndex(idx);
1297}
1298
1299LanguageSet PluginManager::GetAllTypeSystemSupportedLanguagesForTypes() {
1300 const auto &instances = GetTypeSystemInstances().GetInstances();
1301 LanguageSet all;
1302 for (unsigned i = 0; i < instances.size(); ++i)
1303 all.bitvector |= instances[i].supported_languages_for_types.bitvector;
1304 return all;
1305}
1306
1307LanguageSet PluginManager::GetAllTypeSystemSupportedLanguagesForExpressions() {
1308 const auto &instances = GetTypeSystemInstances().GetInstances();
1309 LanguageSet all;
1310 for (unsigned i = 0; i < instances.size(); ++i)
1311 all.bitvector |= instances[i].supported_languages_for_expressions.bitvector;
1312 return all;
1313}
1314
1315#pragma mark REPL
1316
1317struct REPLInstance : public PluginInstance<REPLCreateInstance> {
1318 REPLInstance(llvm::StringRef name, llvm::StringRef description,
1319 CallbackType create_callback, LanguageSet supported_languages)
1320 : PluginInstance<REPLCreateInstance>(name, description, create_callback),
1321 supported_languages(supported_languages) {}
1322
1323 LanguageSet supported_languages;
1324};
1325
1326typedef PluginInstances<REPLInstance> REPLInstances;
1327
1328static REPLInstances &GetREPLInstances() {
1329 static REPLInstances g_instances;
1330 return g_instances;
1331}
1332
1333bool PluginManager::RegisterPlugin(llvm::StringRef name, llvm::StringRef description,
1334 REPLCreateInstance create_callback,
1335 LanguageSet supported_languages) {
1336 return GetREPLInstances().RegisterPlugin(name, description, create_callback,
1337 supported_languages);
1338}
1339
1340bool PluginManager::UnregisterPlugin(REPLCreateInstance create_callback) {
1341 return GetREPLInstances().UnregisterPlugin(create_callback);
1342}
1343
1344REPLCreateInstance PluginManager::GetREPLCreateCallbackAtIndex(uint32_t idx) {
1345 return GetREPLInstances().GetCallbackAtIndex(idx);
1346}
1347
1348LanguageSet PluginManager::GetREPLSupportedLanguagesAtIndex(uint32_t idx) {
1349 const auto &instances = GetREPLInstances().GetInstances();
1350 return idx < instances.size() ? instances[idx].supported_languages
1351 : LanguageSet();
1352}
1353
1354LanguageSet PluginManager::GetREPLAllTypeSystemSupportedLanguages() {
1355 const auto &instances = GetREPLInstances().GetInstances();
1356 LanguageSet all;
1357 for (unsigned i = 0; i < instances.size(); ++i)
1358 all.bitvector |= instances[i].supported_languages.bitvector;
1359 return all;
1360}
1361
1362#pragma mark PluginManager
1363
1364void PluginManager::DebuggerInitialize(Debugger &debugger) {
1365 GetDynamicLoaderInstances().PerformDebuggerCallback(debugger);
1366 GetJITLoaderInstances().PerformDebuggerCallback(debugger);
1367 GetPlatformInstances().PerformDebuggerCallback(debugger);
1368 GetProcessInstances().PerformDebuggerCallback(debugger);
1369 GetSymbolFileInstances().PerformDebuggerCallback(debugger);
1370 GetOperatingSystemInstances().PerformDebuggerCallback(debugger);
1371 GetStructuredDataPluginInstances().PerformDebuggerCallback(debugger);
1372 GetTracePluginInstances().PerformDebuggerCallback(debugger);
1373}
1374
1375// This is the preferred new way to register plugin specific settings. e.g.
1376// This will put a plugin's settings under e.g.
1377// "plugin.<plugin_type_name>.<plugin_type_desc>.SETTINGNAME".
1378static lldb::OptionValuePropertiesSP
1379GetDebuggerPropertyForPlugins(Debugger &debugger, ConstString plugin_type_name,
1380 ConstString plugin_type_desc, bool can_create) {
1381 lldb::OptionValuePropertiesSP parent_properties_sp(
1382 debugger.GetValueProperties());
1383 if (parent_properties_sp) {
1384 static ConstString g_property_name("plugin");
1385
1386 OptionValuePropertiesSP plugin_properties_sp =
1387 parent_properties_sp->GetSubProperty(nullptr, g_property_name);
1388 if (!plugin_properties_sp && can_create) {
1389 plugin_properties_sp =
1390 std::make_shared<OptionValueProperties>(g_property_name);
1391 parent_properties_sp->AppendProperty(
1392 g_property_name, ConstString("Settings specify to plugins."), true,
1393 plugin_properties_sp);
1394 }
1395
1396 if (plugin_properties_sp) {
1397 lldb::OptionValuePropertiesSP plugin_type_properties_sp =
1398 plugin_properties_sp->GetSubProperty(nullptr, plugin_type_name);
1399 if (!plugin_type_properties_sp && can_create) {
1400 plugin_type_properties_sp =
1401 std::make_shared<OptionValueProperties>(plugin_type_name);
1402 plugin_properties_sp->AppendProperty(plugin_type_name, plugin_type_desc,
1403 true, plugin_type_properties_sp);
1404 }
1405 return plugin_type_properties_sp;
1406 }
1407 }
1408 return lldb::OptionValuePropertiesSP();
1409}
1410
1411// This is deprecated way to register plugin specific settings. e.g.
1412// "<plugin_type_name>.plugin.<plugin_type_desc>.SETTINGNAME" and Platform
1413// generic settings would be under "platform.SETTINGNAME".
1414static lldb::OptionValuePropertiesSP GetDebuggerPropertyForPluginsOldStyle(
1415 Debugger &debugger, ConstString plugin_type_name,
1416 ConstString plugin_type_desc, bool can_create) {
1417 static ConstString g_property_name("plugin");
1418 lldb::OptionValuePropertiesSP parent_properties_sp(
1419 debugger.GetValueProperties());
1420 if (parent_properties_sp) {
1421 OptionValuePropertiesSP plugin_properties_sp =
1422 parent_properties_sp->GetSubProperty(nullptr, plugin_type_name);
1423 if (!plugin_properties_sp && can_create) {
1424 plugin_properties_sp =
1425 std::make_shared<OptionValueProperties>(plugin_type_name);
1426 parent_properties_sp->AppendProperty(plugin_type_name, plugin_type_desc,
1427 true, plugin_properties_sp);
1428 }
1429
1430 if (plugin_properties_sp) {
1431 lldb::OptionValuePropertiesSP plugin_type_properties_sp =
1432 plugin_properties_sp->GetSubProperty(nullptr, g_property_name);
1433 if (!plugin_type_properties_sp && can_create) {
1434 plugin_type_properties_sp =
1435 std::make_shared<OptionValueProperties>(g_property_name);
1436 plugin_properties_sp->AppendProperty(
1437 g_property_name, ConstString("Settings specific to plugins"), true,
1438 plugin_type_properties_sp);
1439 }
1440 return plugin_type_properties_sp;
1441 }
1442 }
1443 return lldb::OptionValuePropertiesSP();
1444}
1445
1446namespace {
1447
1448typedef lldb::OptionValuePropertiesSP
1449GetDebuggerPropertyForPluginsPtr(Debugger &, ConstString, ConstString,
1450 bool can_create);
1451}
1452
1453static lldb::OptionValuePropertiesSP
1454GetSettingForPlugin(Debugger &debugger, ConstString setting_name,
1455 ConstString plugin_type_name,
1456 GetDebuggerPropertyForPluginsPtr get_debugger_property =
1457 GetDebuggerPropertyForPlugins) {
1458 lldb::OptionValuePropertiesSP properties_sp;
1459 lldb::OptionValuePropertiesSP plugin_type_properties_sp(get_debugger_property(
1460 debugger, plugin_type_name,
1461 ConstString(), // not creating to so we don't need the description
1462 false));
1463 if (plugin_type_properties_sp)
1464 properties_sp =
1465 plugin_type_properties_sp->GetSubProperty(nullptr, setting_name);
1466 return properties_sp;
1467}
1468
1469static bool
1470CreateSettingForPlugin(Debugger &debugger, ConstString plugin_type_name,
1471 ConstString plugin_type_desc,
1472 const lldb::OptionValuePropertiesSP &properties_sp,
1473 ConstString description, bool is_global_property,
1474 GetDebuggerPropertyForPluginsPtr get_debugger_property =
1475 GetDebuggerPropertyForPlugins) {
1476 if (properties_sp) {
1477 lldb::OptionValuePropertiesSP plugin_type_properties_sp(
1478 get_debugger_property(debugger, plugin_type_name, plugin_type_desc,
1479 true));
1480 if (plugin_type_properties_sp) {
1481 plugin_type_properties_sp->AppendProperty(properties_sp->GetName(),
1482 description, is_global_property,
1483 properties_sp);
1484 return true;
1485 }
1486 }
1487 return false;
1488}
1489
1490static const char *kDynamicLoaderPluginName("dynamic-loader");
1491static const char *kPlatformPluginName("platform");
1492static const char *kProcessPluginName("process");
1493static const char *kSymbolFilePluginName("symbol-file");
1494static const char *kJITLoaderPluginName("jit-loader");
1495static const char *kStructuredDataPluginName("structured-data");
1496
1497lldb::OptionValuePropertiesSP
1498PluginManager::GetSettingForDynamicLoaderPlugin(Debugger &debugger,
1499 ConstString setting_name) {
1500 return GetSettingForPlugin(debugger, setting_name,
1501 ConstString(kDynamicLoaderPluginName));
1502}
1503
1504bool PluginManager::CreateSettingForDynamicLoaderPlugin(
1505 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
1506 ConstString description, bool is_global_property) {
1507 return CreateSettingForPlugin(
1508 debugger, ConstString(kDynamicLoaderPluginName),
1509 ConstString("Settings for dynamic loader plug-ins"), properties_sp,
1510 description, is_global_property);
1511}
1512
1513lldb::OptionValuePropertiesSP
1514PluginManager::GetSettingForPlatformPlugin(Debugger &debugger,
1515 ConstString setting_name) {
1516 return GetSettingForPlugin(debugger, setting_name,
1517 ConstString(kPlatformPluginName),
1518 GetDebuggerPropertyForPluginsOldStyle);
1519}
1520
1521bool PluginManager::CreateSettingForPlatformPlugin(
1522 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
1523 ConstString description, bool is_global_property) {
1524 return CreateSettingForPlugin(debugger, ConstString(kPlatformPluginName),
1525 ConstString("Settings for platform plug-ins"),
1526 properties_sp, description, is_global_property,
1527 GetDebuggerPropertyForPluginsOldStyle);
1528}
1529
1530lldb::OptionValuePropertiesSP
1531PluginManager::GetSettingForProcessPlugin(Debugger &debugger,
1532 ConstString setting_name) {
1533 return GetSettingForPlugin(debugger, setting_name,
1534 ConstString(kProcessPluginName));
1535}
1536
1537bool PluginManager::CreateSettingForProcessPlugin(
1538 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
1539 ConstString description, bool is_global_property) {
1540 return CreateSettingForPlugin(debugger, ConstString(kProcessPluginName),
1541 ConstString("Settings for process plug-ins"),
1542 properties_sp, description, is_global_property);
1543}
1544
1545lldb::OptionValuePropertiesSP
1546PluginManager::GetSettingForSymbolFilePlugin(Debugger &debugger,
1547 ConstString setting_name) {
1548 return GetSettingForPlugin(debugger, setting_name,
1549 ConstString(kSymbolFilePluginName));
1550}
1551
1552bool PluginManager::CreateSettingForSymbolFilePlugin(
1553 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
1554 ConstString description, bool is_global_property) {
1555 return CreateSettingForPlugin(
1556 debugger, ConstString(kSymbolFilePluginName),
1557 ConstString("Settings for symbol file plug-ins"), properties_sp,
1558 description, is_global_property);
1559}
1560
1561lldb::OptionValuePropertiesSP
1562PluginManager::GetSettingForJITLoaderPlugin(Debugger &debugger,
1563 ConstString setting_name) {
1564 return GetSettingForPlugin(debugger, setting_name,
1565 ConstString(kJITLoaderPluginName));
1566}
1567
1568bool PluginManager::CreateSettingForJITLoaderPlugin(
1569 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
1570 ConstString description, bool is_global_property) {
1571 return CreateSettingForPlugin(debugger, ConstString(kJITLoaderPluginName),
1572 ConstString("Settings for JIT loader plug-ins"),
1573 properties_sp, description, is_global_property);
1574}
1575
1576static const char *kOperatingSystemPluginName("os");
1577
1578lldb::OptionValuePropertiesSP
1579PluginManager::GetSettingForOperatingSystemPlugin(Debugger &debugger,
1580 ConstString setting_name) {
1581 lldb::OptionValuePropertiesSP properties_sp;
1582 lldb::OptionValuePropertiesSP plugin_type_properties_sp(
1583 GetDebuggerPropertyForPlugins(
1584 debugger, ConstString(kOperatingSystemPluginName),
1585 ConstString(), // not creating to so we don't need the description
1586 false));
1587 if (plugin_type_properties_sp)
1588 properties_sp =
1589 plugin_type_properties_sp->GetSubProperty(nullptr, setting_name);
1590 return properties_sp;
1591}
1592
1593bool PluginManager::CreateSettingForOperatingSystemPlugin(
1594 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
1595 ConstString description, bool is_global_property) {
1596 if (properties_sp) {
1597 lldb::OptionValuePropertiesSP plugin_type_properties_sp(
1598 GetDebuggerPropertyForPlugins(
1599 debugger, ConstString(kOperatingSystemPluginName),
1600 ConstString("Settings for operating system plug-ins"), true));
1601 if (plugin_type_properties_sp) {
1602 plugin_type_properties_sp->AppendProperty(properties_sp->GetName(),
1603 description, is_global_property,
1604 properties_sp);
1605 return true;
1606 }
1607 }
1608 return false;
1609}
1610
1611lldb::OptionValuePropertiesSP
1612PluginManager::GetSettingForStructuredDataPlugin(Debugger &debugger,
1613 ConstString setting_name) {
1614 return GetSettingForPlugin(debugger, setting_name,
1615 ConstString(kStructuredDataPluginName));
1616}
1617
1618bool PluginManager::CreateSettingForStructuredDataPlugin(
1619 Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
1620 ConstString description, bool is_global_property) {
1621 return CreateSettingForPlugin(
1622 debugger, ConstString(kStructuredDataPluginName),
1623 ConstString("Settings for structured data plug-ins"), properties_sp,
1624 description, is_global_property);
1625}

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

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