Bug Summary

File:build/llvm-toolchain-snapshot-15~++20220420111733+e13d2efed663/llvm/include/llvm/ADT/SmallBitVector.h
Warning:line 97, column 5
Use of memory after it is freed

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name PluginManager.cpp -analyzer-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-15~++20220420111733+e13d2efed663/build-llvm/tools/clang/stage2-bins -resource-dir /usr/lib/llvm-15/lib/clang/15.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-15~++20220420111733+e13d2efed663/lldb/source/Core -I /build/llvm-toolchain-snapshot-15~++20220420111733+e13d2efed663/lldb/include -I tools/lldb/include -I include -I /build/llvm-toolchain-snapshot-15~++20220420111733+e13d2efed663/llvm/include -I /usr/include/python3.9 -I /build/llvm-toolchain-snapshot-15~++20220420111733+e13d2efed663/clang/include -I tools/lldb/../clang/include -I /build/llvm-toolchain-snapshot-15~++20220420111733+e13d2efed663/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-15/lib/clang/15.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-15~++20220420111733+e13d2efed663/build-llvm/tools/clang/stage2-bins=build-llvm/tools/clang/stage2-bins -fmacro-prefix-map=/build/llvm-toolchain-snapshot-15~++20220420111733+e13d2efed663/= -fcoverage-prefix-map=/build/llvm-toolchain-snapshot-15~++20220420111733+e13d2efed663/build-llvm/tools/clang/stage2-bins=build-llvm/tools/clang/stage2-bins -fcoverage-prefix-map=/build/llvm-toolchain-snapshot-15~++20220420111733+e13d2efed663/= -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-stringop-truncation -std=c++14 -fdeprecated-macro -fdebug-compilation-dir=/build/llvm-toolchain-snapshot-15~++20220420111733+e13d2efed663/build-llvm/tools/clang/stage2-bins -fdebug-prefix-map=/build/llvm-toolchain-snapshot-15~++20220420111733+e13d2efed663/build-llvm/tools/clang/stage2-bins=build-llvm/tools/clang/stage2-bins -fdebug-prefix-map=/build/llvm-toolchain-snapshot-15~++20220420111733+e13d2efed663/= -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-04-20-140412-16051-1 -x c++ /build/llvm-toolchain-snapshot-15~++20220420111733+e13d2efed663/lldb/source/Core/PluginManager.cpp

/build/llvm-toolchain-snapshot-15~++20220420111733+e13d2efed663/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-15~++20220420111733+e13d2efed663/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-15~++20220420111733+e13d2efed663/llvm/include/llvm/ADT/SmallBitVector.h

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