Bug Summary

File:src/gnu/usr.bin/clang/liblldbPluginSymbolFile/../../../llvm/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
Warning:line 757, column 23
Called C++ object pointer is null

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.0 -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name SymbolFilePDB.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 -mrelocation-model static -mframe-pointer=all -relaxed-aliasing -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/usr/src/gnu/usr.bin/clang/liblldbPluginSymbolFile/obj -resource-dir /usr/local/lib/clang/13.0.0 -I /usr/src/gnu/usr.bin/clang/liblldbPluginSymbolFile/../../../llvm/llvm/include -I /usr/src/gnu/usr.bin/clang/liblldbPluginSymbolFile/../include -I /usr/src/gnu/usr.bin/clang/liblldbPluginSymbolFile/obj -I /usr/src/gnu/usr.bin/clang/liblldbPluginSymbolFile/obj/../include -D NDEBUG -D __STDC_LIMIT_MACROS -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D LLVM_PREFIX="/usr" -I /usr/src/gnu/usr.bin/clang/liblldbPluginSymbolFile/../../../llvm/lldb/include -I /usr/src/gnu/usr.bin/clang/liblldbPluginSymbolFile/../../../llvm/lldb/source -I /usr/src/gnu/usr.bin/clang/liblldbPluginSymbolFile/../../../llvm/clang/include -I /usr/src/gnu/usr.bin/clang/liblldbPluginSymbolFile/obj/../include/lldb/Plugins -internal-isystem /usr/include/c++/v1 -internal-isystem /usr/local/lib/clang/13.0.0/include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -Wno-comment -std=c++14 -fdeprecated-macro -fdebug-compilation-dir=/usr/src/gnu/usr.bin/clang/liblldbPluginSymbolFile/obj -ferror-limit 19 -fvisibility-inlines-hidden -fwrapv -stack-protector 2 -fno-rtti -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-valloc -fno-builtin-free -fno-builtin-strdup -fno-builtin-strndup -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /home/ben/Projects/vmm/scan-build/2022-01-12-194120-40624-1 -x c++ /usr/src/gnu/usr.bin/clang/liblldbPluginSymbolFile/../../../llvm/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp

/usr/src/gnu/usr.bin/clang/liblldbPluginSymbolFile/../../../llvm/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp

1//===-- SymbolFilePDB.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 "SymbolFilePDB.h"
10
11#include "PDBASTParser.h"
12#include "PDBLocationToDWARFExpression.h"
13
14#include "clang/Lex/Lexer.h"
15
16#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
17#include "lldb/Core/Module.h"
18#include "lldb/Core/PluginManager.h"
19#include "lldb/Symbol/CompileUnit.h"
20#include "lldb/Symbol/LineTable.h"
21#include "lldb/Symbol/ObjectFile.h"
22#include "lldb/Symbol/SymbolContext.h"
23#include "lldb/Symbol/SymbolVendor.h"
24#include "lldb/Symbol/TypeList.h"
25#include "lldb/Symbol/TypeMap.h"
26#include "lldb/Symbol/Variable.h"
27#include "lldb/Utility/Log.h"
28#include "lldb/Utility/RegularExpression.h"
29
30#include "llvm/DebugInfo/PDB/GenericError.h"
31#include "llvm/DebugInfo/PDB/IPDBDataStream.h"
32#include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"
33#include "llvm/DebugInfo/PDB/IPDBLineNumber.h"
34#include "llvm/DebugInfo/PDB/IPDBSectionContrib.h"
35#include "llvm/DebugInfo/PDB/IPDBSourceFile.h"
36#include "llvm/DebugInfo/PDB/IPDBTable.h"
37#include "llvm/DebugInfo/PDB/PDBSymbol.h"
38#include "llvm/DebugInfo/PDB/PDBSymbolBlock.h"
39#include "llvm/DebugInfo/PDB/PDBSymbolCompiland.h"
40#include "llvm/DebugInfo/PDB/PDBSymbolCompilandDetails.h"
41#include "llvm/DebugInfo/PDB/PDBSymbolData.h"
42#include "llvm/DebugInfo/PDB/PDBSymbolExe.h"
43#include "llvm/DebugInfo/PDB/PDBSymbolFunc.h"
44#include "llvm/DebugInfo/PDB/PDBSymbolFuncDebugEnd.h"
45#include "llvm/DebugInfo/PDB/PDBSymbolFuncDebugStart.h"
46#include "llvm/DebugInfo/PDB/PDBSymbolPublicSymbol.h"
47#include "llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h"
48#include "llvm/DebugInfo/PDB/PDBSymbolTypeTypedef.h"
49#include "llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h"
50
51#include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h"
52#include "Plugins/Language/CPlusPlus/MSVCUndecoratedNameParser.h"
53#include "Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h"
54
55using namespace lldb;
56using namespace lldb_private;
57using namespace llvm::pdb;
58
59LLDB_PLUGIN_DEFINE(SymbolFilePDB)namespace lldb_private { void lldb_initialize_SymbolFilePDB()
{ SymbolFilePDB::Initialize(); } void lldb_terminate_SymbolFilePDB
() { SymbolFilePDB::Terminate(); } }
60
61char SymbolFilePDB::ID;
62
63namespace {
64lldb::LanguageType TranslateLanguage(PDB_Lang lang) {
65 switch (lang) {
66 case PDB_Lang::Cpp:
67 return lldb::LanguageType::eLanguageTypeC_plus_plus;
68 case PDB_Lang::C:
69 return lldb::LanguageType::eLanguageTypeC;
70 case PDB_Lang::Swift:
71 return lldb::LanguageType::eLanguageTypeSwift;
72 default:
73 return lldb::LanguageType::eLanguageTypeUnknown;
74 }
75}
76
77bool ShouldAddLine(uint32_t requested_line, uint32_t actual_line,
78 uint32_t addr_length) {
79 return ((requested_line == 0 || actual_line == requested_line) &&
80 addr_length > 0);
81}
82} // namespace
83
84static bool ShouldUseNativeReader() {
85#if defined(_WIN32)
86 llvm::StringRef use_native = ::getenv("LLDB_USE_NATIVE_PDB_READER");
87 return use_native.equals_insensitive("on") ||
88 use_native.equals_insensitive("yes") ||
89 use_native.equals_insensitive("1") ||
90 use_native.equals_insensitive("true");
91#else
92 return true;
93#endif
94}
95
96void SymbolFilePDB::Initialize() {
97 if (ShouldUseNativeReader()) {
98 npdb::SymbolFileNativePDB::Initialize();
99 } else {
100 PluginManager::RegisterPlugin(GetPluginNameStatic(),
101 GetPluginDescriptionStatic(), CreateInstance,
102 DebuggerInitialize);
103 }
104}
105
106void SymbolFilePDB::Terminate() {
107 if (ShouldUseNativeReader()) {
108 npdb::SymbolFileNativePDB::Terminate();
109 } else {
110 PluginManager::UnregisterPlugin(CreateInstance);
111 }
112}
113
114void SymbolFilePDB::DebuggerInitialize(lldb_private::Debugger &debugger) {}
115
116lldb_private::ConstString SymbolFilePDB::GetPluginNameStatic() {
117 static ConstString g_name("pdb");
118 return g_name;
119}
120
121const char *SymbolFilePDB::GetPluginDescriptionStatic() {
122 return "Microsoft PDB debug symbol file reader.";
123}
124
125lldb_private::SymbolFile *
126SymbolFilePDB::CreateInstance(ObjectFileSP objfile_sp) {
127 return new SymbolFilePDB(std::move(objfile_sp));
128}
129
130SymbolFilePDB::SymbolFilePDB(lldb::ObjectFileSP objfile_sp)
131 : SymbolFile(std::move(objfile_sp)), m_session_up(), m_global_scope_up() {}
132
133SymbolFilePDB::~SymbolFilePDB() = default;
134
135uint32_t SymbolFilePDB::CalculateAbilities() {
136 uint32_t abilities = 0;
137 if (!m_objfile_sp)
138 return 0;
139
140 if (!m_session_up) {
141 // Lazily load and match the PDB file, but only do this once.
142 std::string exePath = m_objfile_sp->GetFileSpec().GetPath();
143 auto error = loadDataForEXE(PDB_ReaderType::DIA, llvm::StringRef(exePath),
144 m_session_up);
145 if (error) {
146 llvm::consumeError(std::move(error));
147 auto module_sp = m_objfile_sp->GetModule();
148 if (!module_sp)
149 return 0;
150 // See if any symbol file is specified through `--symfile` option.
151 FileSpec symfile = module_sp->GetSymbolFileFileSpec();
152 if (!symfile)
153 return 0;
154 error = loadDataForPDB(PDB_ReaderType::DIA,
155 llvm::StringRef(symfile.GetPath()), m_session_up);
156 if (error) {
157 llvm::consumeError(std::move(error));
158 return 0;
159 }
160 }
161 }
162 if (!m_session_up)
163 return 0;
164
165 auto enum_tables_up = m_session_up->getEnumTables();
166 if (!enum_tables_up)
167 return 0;
168 while (auto table_up = enum_tables_up->getNext()) {
169 if (table_up->getItemCount() == 0)
170 continue;
171 auto type = table_up->getTableType();
172 switch (type) {
173 case PDB_TableType::Symbols:
174 // This table represents a store of symbols with types listed in
175 // PDBSym_Type
176 abilities |= (CompileUnits | Functions | Blocks | GlobalVariables |
177 LocalVariables | VariableTypes);
178 break;
179 case PDB_TableType::LineNumbers:
180 abilities |= LineTables;
181 break;
182 default:
183 break;
184 }
185 }
186 return abilities;
187}
188
189void SymbolFilePDB::InitializeObject() {
190 lldb::addr_t obj_load_address =
191 m_objfile_sp->GetBaseAddress().GetFileAddress();
192 lldbassert(obj_load_address && obj_load_address != LLDB_INVALID_ADDRESS)lldb_private::lldb_assert(static_cast<bool>(obj_load_address
&& obj_load_address != 0xffffffffffffffffULL), "obj_load_address && obj_load_address != LLDB_INVALID_ADDRESS"
, __FUNCTION__, "/usr/src/gnu/usr.bin/clang/liblldbPluginSymbolFile/../../../llvm/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp"
, 192)
;
193 m_session_up->setLoadAddress(obj_load_address);
194 if (!m_global_scope_up)
195 m_global_scope_up = m_session_up->getGlobalScope();
196 lldbassert(m_global_scope_up.get())lldb_private::lldb_assert(static_cast<bool>(m_global_scope_up
.get()), "m_global_scope_up.get()", __FUNCTION__, "/usr/src/gnu/usr.bin/clang/liblldbPluginSymbolFile/../../../llvm/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp"
, 196)
;
197}
198
199uint32_t SymbolFilePDB::CalculateNumCompileUnits() {
200 auto compilands = m_global_scope_up->findAllChildren<PDBSymbolCompiland>();
201 if (!compilands)
202 return 0;
203
204 // The linker could link *.dll (compiland language = LINK), or import
205 // *.dll. For example, a compiland with name `Import:KERNEL32.dll` could be
206 // found as a child of the global scope (PDB executable). Usually, such
207 // compilands contain `thunk` symbols in which we are not interested for
208 // now. However we still count them in the compiland list. If we perform
209 // any compiland related activity, like finding symbols through
210 // llvm::pdb::IPDBSession methods, such compilands will all be searched
211 // automatically no matter whether we include them or not.
212 uint32_t compile_unit_count = compilands->getChildCount();
213
214 // The linker can inject an additional "dummy" compilation unit into the
215 // PDB. Ignore this special compile unit for our purposes, if it is there.
216 // It is always the last one.
217 auto last_compiland_up = compilands->getChildAtIndex(compile_unit_count - 1);
218 lldbassert(last_compiland_up.get())lldb_private::lldb_assert(static_cast<bool>(last_compiland_up
.get()), "last_compiland_up.get()", __FUNCTION__, "/usr/src/gnu/usr.bin/clang/liblldbPluginSymbolFile/../../../llvm/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp"
, 218)
;
219 std::string name = last_compiland_up->getName();
220 if (name == "* Linker *")
221 --compile_unit_count;
222 return compile_unit_count;
223}
224
225void SymbolFilePDB::GetCompileUnitIndex(
226 const llvm::pdb::PDBSymbolCompiland &pdb_compiland, uint32_t &index) {
227 auto results_up = m_global_scope_up->findAllChildren<PDBSymbolCompiland>();
228 if (!results_up)
229 return;
230 auto uid = pdb_compiland.getSymIndexId();
231 for (uint32_t cu_idx = 0; cu_idx < GetNumCompileUnits(); ++cu_idx) {
232 auto compiland_up = results_up->getChildAtIndex(cu_idx);
233 if (!compiland_up)
234 continue;
235 if (compiland_up->getSymIndexId() == uid) {
236 index = cu_idx;
237 return;
238 }
239 }
240 index = UINT32_MAX0xffffffffU;
241 return;
242}
243
244std::unique_ptr<llvm::pdb::PDBSymbolCompiland>
245SymbolFilePDB::GetPDBCompilandByUID(uint32_t uid) {
246 return m_session_up->getConcreteSymbolById<PDBSymbolCompiland>(uid);
247}
248
249lldb::CompUnitSP SymbolFilePDB::ParseCompileUnitAtIndex(uint32_t index) {
250 if (index >= GetNumCompileUnits())
251 return CompUnitSP();
252
253 // Assuming we always retrieve same compilands listed in same order through
254 // `PDBSymbolExe::findAllChildren` method, otherwise using `index` to get a
255 // compile unit makes no sense.
256 auto results = m_global_scope_up->findAllChildren<PDBSymbolCompiland>();
257 if (!results)
258 return CompUnitSP();
259 auto compiland_up = results->getChildAtIndex(index);
260 if (!compiland_up)
261 return CompUnitSP();
262 return ParseCompileUnitForUID(compiland_up->getSymIndexId(), index);
263}
264
265lldb::LanguageType SymbolFilePDB::ParseLanguage(CompileUnit &comp_unit) {
266 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
267 auto compiland_up = GetPDBCompilandByUID(comp_unit.GetID());
268 if (!compiland_up)
269 return lldb::eLanguageTypeUnknown;
270 auto details = compiland_up->findOneChild<PDBSymbolCompilandDetails>();
271 if (!details)
272 return lldb::eLanguageTypeUnknown;
273 return TranslateLanguage(details->getLanguage());
274}
275
276lldb_private::Function *
277SymbolFilePDB::ParseCompileUnitFunctionForPDBFunc(const PDBSymbolFunc &pdb_func,
278 CompileUnit &comp_unit) {
279 if (FunctionSP result = comp_unit.FindFunctionByUID(pdb_func.getSymIndexId()))
280 return result.get();
281
282 auto file_vm_addr = pdb_func.getVirtualAddress();
283 if (file_vm_addr == LLDB_INVALID_ADDRESS0xffffffffffffffffULL || file_vm_addr == 0)
284 return nullptr;
285
286 auto func_length = pdb_func.getLength();
287 AddressRange func_range =
288 AddressRange(file_vm_addr, func_length,
289 GetObjectFile()->GetModule()->GetSectionList());
290 if (!func_range.GetBaseAddress().IsValid())
291 return nullptr;
292
293 lldb_private::Type *func_type = ResolveTypeUID(pdb_func.getSymIndexId());
294 if (!func_type)
295 return nullptr;
296
297 user_id_t func_type_uid = pdb_func.getSignatureId();
298
299 Mangled mangled = GetMangledForPDBFunc(pdb_func);
300
301 FunctionSP func_sp =
302 std::make_shared<Function>(&comp_unit, pdb_func.getSymIndexId(),
303 func_type_uid, mangled, func_type, func_range);
304
305 comp_unit.AddFunction(func_sp);
306
307 LanguageType lang = ParseLanguage(comp_unit);
308 auto type_system_or_err = GetTypeSystemForLanguage(lang);
309 if (auto err = type_system_or_err.takeError()) {
310 LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS),do { ::lldb_private::Log *log_private = (lldb_private::GetLogIfAnyCategoriesSet
((1u << 20))); ::llvm::Error error_private = (std::move
(err)); if (log_private && error_private) { log_private
->FormatError(::std::move(error_private), "/usr/src/gnu/usr.bin/clang/liblldbPluginSymbolFile/../../../llvm/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp"
, __func__, "Unable to parse PDBFunc"); } else ::llvm::consumeError
(::std::move(error_private)); } while (0)
311 std::move(err), "Unable to parse PDBFunc")do { ::lldb_private::Log *log_private = (lldb_private::GetLogIfAnyCategoriesSet
((1u << 20))); ::llvm::Error error_private = (std::move
(err)); if (log_private && error_private) { log_private
->FormatError(::std::move(error_private), "/usr/src/gnu/usr.bin/clang/liblldbPluginSymbolFile/../../../llvm/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp"
, __func__, "Unable to parse PDBFunc"); } else ::llvm::consumeError
(::std::move(error_private)); } while (0)
;
312 return nullptr;
313 }
314
315 TypeSystemClang *clang_type_system =
316 llvm::dyn_cast_or_null<TypeSystemClang>(&type_system_or_err.get());
317 if (!clang_type_system)
318 return nullptr;
319 clang_type_system->GetPDBParser()->GetDeclForSymbol(pdb_func);
320
321 return func_sp.get();
322}
323
324size_t SymbolFilePDB::ParseFunctions(CompileUnit &comp_unit) {
325 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
326 size_t func_added = 0;
327 auto compiland_up = GetPDBCompilandByUID(comp_unit.GetID());
328 if (!compiland_up)
329 return 0;
330 auto results_up = compiland_up->findAllChildren<PDBSymbolFunc>();
331 if (!results_up)
332 return 0;
333 while (auto pdb_func_up = results_up->getNext()) {
334 auto func_sp = comp_unit.FindFunctionByUID(pdb_func_up->getSymIndexId());
335 if (!func_sp) {
336 if (ParseCompileUnitFunctionForPDBFunc(*pdb_func_up, comp_unit))
337 ++func_added;
338 }
339 }
340 return func_added;
341}
342
343bool SymbolFilePDB::ParseLineTable(CompileUnit &comp_unit) {
344 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
345 if (comp_unit.GetLineTable())
346 return true;
347 return ParseCompileUnitLineTable(comp_unit, 0);
348}
349
350bool SymbolFilePDB::ParseDebugMacros(CompileUnit &comp_unit) {
351 // PDB doesn't contain information about macros
352 return false;
353}
354
355bool SymbolFilePDB::ParseSupportFiles(
356 CompileUnit &comp_unit, lldb_private::FileSpecList &support_files) {
357
358 // In theory this is unnecessary work for us, because all of this information
359 // is easily (and quickly) accessible from DebugInfoPDB, so caching it a
360 // second time seems like a waste. Unfortunately, there's no good way around
361 // this short of a moderate refactor since SymbolVendor depends on being able
362 // to cache this list.
363 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
364 auto compiland_up = GetPDBCompilandByUID(comp_unit.GetID());
365 if (!compiland_up)
366 return false;
367 auto files = m_session_up->getSourceFilesForCompiland(*compiland_up);
368 if (!files || files->getChildCount() == 0)
369 return false;
370
371 while (auto file = files->getNext()) {
372 FileSpec spec(file->getFileName(), FileSpec::Style::windows);
373 support_files.AppendIfUnique(spec);
374 }
375
376 return true;
377}
378
379bool SymbolFilePDB::ParseImportedModules(
380 const lldb_private::SymbolContext &sc,
381 std::vector<SourceModule> &imported_modules) {
382 // PDB does not yet support module debug info
383 return false;
384}
385
386static size_t ParseFunctionBlocksForPDBSymbol(
387 uint64_t func_file_vm_addr, const llvm::pdb::PDBSymbol *pdb_symbol,
388 lldb_private::Block *parent_block, bool is_top_parent) {
389 assert(pdb_symbol && parent_block)((void)0);
390
391 size_t num_added = 0;
392 switch (pdb_symbol->getSymTag()) {
393 case PDB_SymType::Block:
394 case PDB_SymType::Function: {
395 Block *block = nullptr;
396 auto &raw_sym = pdb_symbol->getRawSymbol();
397 if (auto *pdb_func = llvm::dyn_cast<PDBSymbolFunc>(pdb_symbol)) {
398 if (pdb_func->hasNoInlineAttribute())
399 break;
400 if (is_top_parent)
401 block = parent_block;
402 else
403 break;
404 } else if (llvm::dyn_cast<PDBSymbolBlock>(pdb_symbol)) {
405 auto uid = pdb_symbol->getSymIndexId();
406 if (parent_block->FindBlockByID(uid))
407 break;
408 if (raw_sym.getVirtualAddress() < func_file_vm_addr)
409 break;
410
411 auto block_sp = std::make_shared<Block>(pdb_symbol->getSymIndexId());
412 parent_block->AddChild(block_sp);
413 block = block_sp.get();
414 } else
415 llvm_unreachable("Unexpected PDB symbol!")__builtin_unreachable();
416
417 block->AddRange(Block::Range(
418 raw_sym.getVirtualAddress() - func_file_vm_addr, raw_sym.getLength()));
419 block->FinalizeRanges();
420 ++num_added;
421
422 auto results_up = pdb_symbol->findAllChildren();
423 if (!results_up)
424 break;
425 while (auto symbol_up = results_up->getNext()) {
426 num_added += ParseFunctionBlocksForPDBSymbol(
427 func_file_vm_addr, symbol_up.get(), block, false);
428 }
429 } break;
430 default:
431 break;
432 }
433 return num_added;
434}
435
436size_t SymbolFilePDB::ParseBlocksRecursive(Function &func) {
437 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
438 size_t num_added = 0;
439 auto uid = func.GetID();
440 auto pdb_func_up = m_session_up->getConcreteSymbolById<PDBSymbolFunc>(uid);
441 if (!pdb_func_up)
442 return 0;
443 Block &parent_block = func.GetBlock(false);
444 num_added = ParseFunctionBlocksForPDBSymbol(
445 pdb_func_up->getVirtualAddress(), pdb_func_up.get(), &parent_block, true);
446 return num_added;
447}
448
449size_t SymbolFilePDB::ParseTypes(CompileUnit &comp_unit) {
450 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
451
452 size_t num_added = 0;
453 auto compiland = GetPDBCompilandByUID(comp_unit.GetID());
454 if (!compiland)
455 return 0;
456
457 auto ParseTypesByTagFn = [&num_added, this](const PDBSymbol &raw_sym) {
458 std::unique_ptr<IPDBEnumSymbols> results;
459 PDB_SymType tags_to_search[] = {PDB_SymType::Enum, PDB_SymType::Typedef,
460 PDB_SymType::UDT};
461 for (auto tag : tags_to_search) {
462 results = raw_sym.findAllChildren(tag);
463 if (!results || results->getChildCount() == 0)
464 continue;
465 while (auto symbol = results->getNext()) {
466 switch (symbol->getSymTag()) {
467 case PDB_SymType::Enum:
468 case PDB_SymType::UDT:
469 case PDB_SymType::Typedef:
470 break;
471 default:
472 continue;
473 }
474
475 // This should cause the type to get cached and stored in the `m_types`
476 // lookup.
477 if (auto type = ResolveTypeUID(symbol->getSymIndexId())) {
478 // Resolve the type completely to avoid a completion
479 // (and so a list change, which causes an iterators invalidation)
480 // during a TypeList dumping
481 type->GetFullCompilerType();
482 ++num_added;
483 }
484 }
485 }
486 };
487
488 ParseTypesByTagFn(*compiland);
489
490 // Also parse global types particularly coming from this compiland.
491 // Unfortunately, PDB has no compiland information for each global type. We
492 // have to parse them all. But ensure we only do this once.
493 static bool parse_all_global_types = false;
494 if (!parse_all_global_types) {
495 ParseTypesByTagFn(*m_global_scope_up);
496 parse_all_global_types = true;
497 }
498 return num_added;
499}
500
501size_t
502SymbolFilePDB::ParseVariablesForContext(const lldb_private::SymbolContext &sc) {
503 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
504 if (!sc.comp_unit)
505 return 0;
506
507 size_t num_added = 0;
508 if (sc.function) {
509 auto pdb_func = m_session_up->getConcreteSymbolById<PDBSymbolFunc>(
510 sc.function->GetID());
511 if (!pdb_func)
512 return 0;
513
514 num_added += ParseVariables(sc, *pdb_func);
515 sc.function->GetBlock(false).SetDidParseVariables(true, true);
516 } else if (sc.comp_unit) {
517 auto compiland = GetPDBCompilandByUID(sc.comp_unit->GetID());
518 if (!compiland)
519 return 0;
520
521 if (sc.comp_unit->GetVariableList(false))
522 return 0;
523
524 auto results = m_global_scope_up->findAllChildren<PDBSymbolData>();
525 if (results && results->getChildCount()) {
526 while (auto result = results->getNext()) {
527 auto cu_id = GetCompilandId(*result);
528 // FIXME: We are not able to determine variable's compile unit.
529 if (cu_id == 0)
530 continue;
531
532 if (cu_id == sc.comp_unit->GetID())
533 num_added += ParseVariables(sc, *result);
534 }
535 }
536
537 // FIXME: A `file static` or `global constant` variable appears both in
538 // compiland's children and global scope's children with unexpectedly
539 // different symbol's Id making it ambiguous.
540
541 // FIXME: 'local constant', for example, const char var[] = "abc", declared
542 // in a function scope, can't be found in PDB.
543
544 // Parse variables in this compiland.
545 num_added += ParseVariables(sc, *compiland);
546 }
547
548 return num_added;
549}
550
551lldb_private::Type *SymbolFilePDB::ResolveTypeUID(lldb::user_id_t type_uid) {
552 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
553 auto find_result = m_types.find(type_uid);
554 if (find_result != m_types.end())
555 return find_result->second.get();
556
557 auto type_system_or_err =
558 GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);
559 if (auto err = type_system_or_err.takeError()) {
560 LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS),do { ::lldb_private::Log *log_private = (lldb_private::GetLogIfAnyCategoriesSet
((1u << 20))); ::llvm::Error error_private = (std::move
(err)); if (log_private && error_private) { log_private
->FormatError(::std::move(error_private), "/usr/src/gnu/usr.bin/clang/liblldbPluginSymbolFile/../../../llvm/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp"
, __func__, "Unable to ResolveTypeUID"); } else ::llvm::consumeError
(::std::move(error_private)); } while (0)
561 std::move(err), "Unable to ResolveTypeUID")do { ::lldb_private::Log *log_private = (lldb_private::GetLogIfAnyCategoriesSet
((1u << 20))); ::llvm::Error error_private = (std::move
(err)); if (log_private && error_private) { log_private
->FormatError(::std::move(error_private), "/usr/src/gnu/usr.bin/clang/liblldbPluginSymbolFile/../../../llvm/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp"
, __func__, "Unable to ResolveTypeUID"); } else ::llvm::consumeError
(::std::move(error_private)); } while (0)
;
562 return nullptr;
563 }
564
565 TypeSystemClang *clang_type_system =
566 llvm::dyn_cast_or_null<TypeSystemClang>(&type_system_or_err.get());
567 if (!clang_type_system)
568 return nullptr;
569 PDBASTParser *pdb = clang_type_system->GetPDBParser();
570 if (!pdb)
571 return nullptr;
572
573 auto pdb_type = m_session_up->getSymbolById(type_uid);
574 if (pdb_type == nullptr)
575 return nullptr;
576
577 lldb::TypeSP result = pdb->CreateLLDBTypeFromPDBType(*pdb_type);
578 if (result) {
579 m_types.insert(std::make_pair(type_uid, result));
580 GetTypeList().Insert(result);
581 }
582 return result.get();
583}
584
585llvm::Optional<SymbolFile::ArrayInfo> SymbolFilePDB::GetDynamicArrayInfoForUID(
586 lldb::user_id_t type_uid, const lldb_private::ExecutionContext *exe_ctx) {
587 return llvm::None;
588}
589
590bool SymbolFilePDB::CompleteType(lldb_private::CompilerType &compiler_type) {
591 std::lock_guard<std::recursive_mutex> guard(
592 GetObjectFile()->GetModule()->GetMutex());
593
594 auto type_system_or_err =
595 GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);
596 if (auto err = type_system_or_err.takeError()) {
597 LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS),do { ::lldb_private::Log *log_private = (lldb_private::GetLogIfAnyCategoriesSet
((1u << 20))); ::llvm::Error error_private = (std::move
(err)); if (log_private && error_private) { log_private
->FormatError(::std::move(error_private), "/usr/src/gnu/usr.bin/clang/liblldbPluginSymbolFile/../../../llvm/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp"
, __func__, "Unable to get dynamic array info for UID"); } else
::llvm::consumeError(::std::move(error_private)); } while (0
)
598 std::move(err), "Unable to get dynamic array info for UID")do { ::lldb_private::Log *log_private = (lldb_private::GetLogIfAnyCategoriesSet
((1u << 20))); ::llvm::Error error_private = (std::move
(err)); if (log_private && error_private) { log_private
->FormatError(::std::move(error_private), "/usr/src/gnu/usr.bin/clang/liblldbPluginSymbolFile/../../../llvm/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp"
, __func__, "Unable to get dynamic array info for UID"); } else
::llvm::consumeError(::std::move(error_private)); } while (0
)
;
599 return false;
600 }
601
602 TypeSystemClang *clang_ast_ctx =
603 llvm::dyn_cast_or_null<TypeSystemClang>(&type_system_or_err.get());
604
605 if (!clang_ast_ctx)
606 return false;
607
608 PDBASTParser *pdb = clang_ast_ctx->GetPDBParser();
609 if (!pdb)
610 return false;
611
612 return pdb->CompleteTypeFromPDB(compiler_type);
613}
614
615lldb_private::CompilerDecl SymbolFilePDB::GetDeclForUID(lldb::user_id_t uid) {
616 auto type_system_or_err =
617 GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);
618 if (auto err = type_system_or_err.takeError()) {
619 LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS),do { ::lldb_private::Log *log_private = (lldb_private::GetLogIfAnyCategoriesSet
((1u << 20))); ::llvm::Error error_private = (std::move
(err)); if (log_private && error_private) { log_private
->FormatError(::std::move(error_private), "/usr/src/gnu/usr.bin/clang/liblldbPluginSymbolFile/../../../llvm/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp"
, __func__, "Unable to get decl for UID"); } else ::llvm::consumeError
(::std::move(error_private)); } while (0)
620 std::move(err), "Unable to get decl for UID")do { ::lldb_private::Log *log_private = (lldb_private::GetLogIfAnyCategoriesSet
((1u << 20))); ::llvm::Error error_private = (std::move
(err)); if (log_private && error_private) { log_private
->FormatError(::std::move(error_private), "/usr/src/gnu/usr.bin/clang/liblldbPluginSymbolFile/../../../llvm/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp"
, __func__, "Unable to get decl for UID"); } else ::llvm::consumeError
(::std::move(error_private)); } while (0)
;
621 return CompilerDecl();
622 }
623
624 TypeSystemClang *clang_ast_ctx =
625 llvm::dyn_cast_or_null<TypeSystemClang>(&type_system_or_err.get());
626 if (!clang_ast_ctx)
627 return CompilerDecl();
628
629 PDBASTParser *pdb = clang_ast_ctx->GetPDBParser();
630 if (!pdb)
631 return CompilerDecl();
632
633 auto symbol = m_session_up->getSymbolById(uid);
634 if (!symbol)
635 return CompilerDecl();
636
637 auto decl = pdb->GetDeclForSymbol(*symbol);
638 if (!decl)
639 return CompilerDecl();
640
641 return clang_ast_ctx->GetCompilerDecl(decl);
642}
643
644lldb_private::CompilerDeclContext
645SymbolFilePDB::GetDeclContextForUID(lldb::user_id_t uid) {
646 auto type_system_or_err =
647 GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);
648 if (auto err = type_system_or_err.takeError()) {
649 LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS),do { ::lldb_private::Log *log_private = (lldb_private::GetLogIfAnyCategoriesSet
((1u << 20))); ::llvm::Error error_private = (std::move
(err)); if (log_private && error_private) { log_private
->FormatError(::std::move(error_private), "/usr/src/gnu/usr.bin/clang/liblldbPluginSymbolFile/../../../llvm/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp"
, __func__, "Unable to get DeclContext for UID"); } else ::llvm
::consumeError(::std::move(error_private)); } while (0)
650 std::move(err), "Unable to get DeclContext for UID")do { ::lldb_private::Log *log_private = (lldb_private::GetLogIfAnyCategoriesSet
((1u << 20))); ::llvm::Error error_private = (std::move
(err)); if (log_private && error_private) { log_private
->FormatError(::std::move(error_private), "/usr/src/gnu/usr.bin/clang/liblldbPluginSymbolFile/../../../llvm/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp"
, __func__, "Unable to get DeclContext for UID"); } else ::llvm
::consumeError(::std::move(error_private)); } while (0)
;
651 return CompilerDeclContext();
652 }
653
654 TypeSystemClang *clang_ast_ctx =
655 llvm::dyn_cast_or_null<TypeSystemClang>(&type_system_or_err.get());
656 if (!clang_ast_ctx)
657 return CompilerDeclContext();
658
659 PDBASTParser *pdb = clang_ast_ctx->GetPDBParser();
660 if (!pdb)
661 return CompilerDeclContext();
662
663 auto symbol = m_session_up->getSymbolById(uid);
664 if (!symbol)
665 return CompilerDeclContext();
666
667 auto decl_context = pdb->GetDeclContextForSymbol(*symbol);
668 if (!decl_context)
669 return GetDeclContextContainingUID(uid);
670
671 return clang_ast_ctx->CreateDeclContext(decl_context);
672}
673
674lldb_private::CompilerDeclContext
675SymbolFilePDB::GetDeclContextContainingUID(lldb::user_id_t uid) {
676 auto type_system_or_err =
677 GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);
678 if (auto err = type_system_or_err.takeError()) {
679 LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS),do { ::lldb_private::Log *log_private = (lldb_private::GetLogIfAnyCategoriesSet
((1u << 20))); ::llvm::Error error_private = (std::move
(err)); if (log_private && error_private) { log_private
->FormatError(::std::move(error_private), "/usr/src/gnu/usr.bin/clang/liblldbPluginSymbolFile/../../../llvm/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp"
, __func__, "Unable to get DeclContext containing UID"); } else
::llvm::consumeError(::std::move(error_private)); } while (0
)
680 std::move(err), "Unable to get DeclContext containing UID")do { ::lldb_private::Log *log_private = (lldb_private::GetLogIfAnyCategoriesSet
((1u << 20))); ::llvm::Error error_private = (std::move
(err)); if (log_private && error_private) { log_private
->FormatError(::std::move(error_private), "/usr/src/gnu/usr.bin/clang/liblldbPluginSymbolFile/../../../llvm/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp"
, __func__, "Unable to get DeclContext containing UID"); } else
::llvm::consumeError(::std::move(error_private)); } while (0
)
;
681 return CompilerDeclContext();
682 }
683
684 TypeSystemClang *clang_ast_ctx =
685 llvm::dyn_cast_or_null<TypeSystemClang>(&type_system_or_err.get());
686 if (!clang_ast_ctx)
687 return CompilerDeclContext();
688
689 PDBASTParser *pdb = clang_ast_ctx->GetPDBParser();
690 if (!pdb)
691 return CompilerDeclContext();
692
693 auto symbol = m_session_up->getSymbolById(uid);
694 if (!symbol)
695 return CompilerDeclContext();
696
697 auto decl_context = pdb->GetDeclContextContainingSymbol(*symbol);
698 assert(decl_context)((void)0);
699
700 return clang_ast_ctx->CreateDeclContext(decl_context);
701}
702
703void SymbolFilePDB::ParseDeclsForContext(
704 lldb_private::CompilerDeclContext decl_ctx) {
705 auto type_system_or_err =
706 GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);
707 if (auto err = type_system_or_err.takeError()) {
708 LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS),do { ::lldb_private::Log *log_private = (lldb_private::GetLogIfAnyCategoriesSet
((1u << 20))); ::llvm::Error error_private = (std::move
(err)); if (log_private && error_private) { log_private
->FormatError(::std::move(error_private), "/usr/src/gnu/usr.bin/clang/liblldbPluginSymbolFile/../../../llvm/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp"
, __func__, "Unable to parse decls for context"); } else ::llvm
::consumeError(::std::move(error_private)); } while (0)
709 std::move(err), "Unable to parse decls for context")do { ::lldb_private::Log *log_private = (lldb_private::GetLogIfAnyCategoriesSet
((1u << 20))); ::llvm::Error error_private = (std::move
(err)); if (log_private && error_private) { log_private
->FormatError(::std::move(error_private), "/usr/src/gnu/usr.bin/clang/liblldbPluginSymbolFile/../../../llvm/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp"
, __func__, "Unable to parse decls for context"); } else ::llvm
::consumeError(::std::move(error_private)); } while (0)
;
710 return;
711 }
712
713 TypeSystemClang *clang_ast_ctx =
714 llvm::dyn_cast_or_null<TypeSystemClang>(&type_system_or_err.get());
715 if (!clang_ast_ctx)
716 return;
717
718 PDBASTParser *pdb = clang_ast_ctx->GetPDBParser();
719 if (!pdb)
720 return;
721
722 pdb->ParseDeclsForDeclContext(
723 static_cast<clang::DeclContext *>(decl_ctx.GetOpaqueDeclContext()));
724}
725
726uint32_t
727SymbolFilePDB::ResolveSymbolContext(const lldb_private::Address &so_addr,
728 SymbolContextItem resolve_scope,
729 lldb_private::SymbolContext &sc) {
730 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
731 uint32_t resolved_flags = 0;
732 if (resolve_scope & eSymbolContextCompUnit ||
1
Assuming the condition is false
733 resolve_scope & eSymbolContextVariable ||
2
Assuming the condition is false
734 resolve_scope & eSymbolContextFunction ||
3
Assuming the condition is false
735 resolve_scope & eSymbolContextBlock ||
4
Assuming the condition is true
736 resolve_scope & eSymbolContextLineEntry) {
737 auto cu_sp = GetCompileUnitContainsAddress(so_addr);
738 if (!cu_sp) {
5
Calling 'shared_ptr::operator bool'
8
Returning from 'shared_ptr::operator bool'
9
Taking false branch
739 if (resolved_flags & eSymbolContextVariable) {
740 // TODO: Resolve variables
741 }
742 return 0;
743 }
744 sc.comp_unit = cu_sp.get();
745 resolved_flags |= eSymbolContextCompUnit;
746 lldbassert(sc.module_sp == cu_sp->GetModule())lldb_private::lldb_assert(static_cast<bool>(sc.module_sp
== cu_sp->GetModule()), "sc.module_sp == cu_sp->GetModule()"
, __FUNCTION__, "/usr/src/gnu/usr.bin/clang/liblldbPluginSymbolFile/../../../llvm/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp"
, 746)
;
747 }
748
749 if (resolve_scope & eSymbolContextFunction ||
10
Calling 'operator&'
12
Returning from 'operator&'
13
Taking true branch
750 resolve_scope & eSymbolContextBlock) {
751 addr_t file_vm_addr = so_addr.GetFileAddress();
752 auto symbol_up =
753 m_session_up->findSymbolByAddress(file_vm_addr, PDB_SymType::Function);
754 if (symbol_up) {
14
Calling 'unique_ptr::operator bool'
17
Returning from 'unique_ptr::operator bool'
18
Taking true branch
755 auto *pdb_func = llvm::dyn_cast<PDBSymbolFunc>(symbol_up.get());
19
Assuming the object is not a 'PDBSymbolFunc'
20
'pdb_func' initialized to a null pointer value
756 assert(pdb_func)((void)0);
757 auto func_uid = pdb_func->getSymIndexId();
21
Called C++ object pointer is null
758 sc.function = sc.comp_unit->FindFunctionByUID(func_uid).get();
759 if (sc.function == nullptr)
760 sc.function =
761 ParseCompileUnitFunctionForPDBFunc(*pdb_func, *sc.comp_unit);
762 if (sc.function) {
763 resolved_flags |= eSymbolContextFunction;
764 if (resolve_scope & eSymbolContextBlock) {
765 auto block_symbol = m_session_up->findSymbolByAddress(
766 file_vm_addr, PDB_SymType::Block);
767 auto block_id = block_symbol ? block_symbol->getSymIndexId()
768 : sc.function->GetID();
769 sc.block = sc.function->GetBlock(true).FindBlockByID(block_id);
770 if (sc.block)
771 resolved_flags |= eSymbolContextBlock;
772 }
773 }
774 }
775 }
776
777 if (resolve_scope & eSymbolContextLineEntry) {
778 if (auto *line_table = sc.comp_unit->GetLineTable()) {
779 Address addr(so_addr);
780 if (line_table->FindLineEntryByAddress(addr, sc.line_entry))
781 resolved_flags |= eSymbolContextLineEntry;
782 }
783 }
784
785 return resolved_flags;
786}
787
788uint32_t SymbolFilePDB::ResolveSymbolContext(
789 const lldb_private::SourceLocationSpec &src_location_spec,
790 SymbolContextItem resolve_scope, lldb_private::SymbolContextList &sc_list) {
791 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
792 const size_t old_size = sc_list.GetSize();
793 const FileSpec &file_spec = src_location_spec.GetFileSpec();
794 const uint32_t line = src_location_spec.GetLine().getValueOr(0);
795 if (resolve_scope & lldb::eSymbolContextCompUnit) {
796 // Locate all compilation units with line numbers referencing the specified
797 // file. For example, if `file_spec` is <vector>, then this should return
798 // all source files and header files that reference <vector>, either
799 // directly or indirectly.
800 auto compilands = m_session_up->findCompilandsForSourceFile(
801 file_spec.GetPath(), PDB_NameSearchFlags::NS_CaseInsensitive);
802
803 if (!compilands)
804 return 0;
805
806 // For each one, either find its previously parsed data or parse it afresh
807 // and add it to the symbol context list.
808 while (auto compiland = compilands->getNext()) {
809 // If we're not checking inlines, then don't add line information for
810 // this file unless the FileSpec matches. For inline functions, we don't
811 // have to match the FileSpec since they could be defined in headers
812 // other than file specified in FileSpec.
813 if (!src_location_spec.GetCheckInlines()) {
814 std::string source_file = compiland->getSourceFileFullPath();
815 if (source_file.empty())
816 continue;
817 FileSpec this_spec(source_file, FileSpec::Style::windows);
818 bool need_full_match = !file_spec.GetDirectory().IsEmpty();
819 if (FileSpec::Compare(file_spec, this_spec, need_full_match) != 0)
820 continue;
821 }
822
823 SymbolContext sc;
824 auto cu = ParseCompileUnitForUID(compiland->getSymIndexId());
825 if (!cu)
826 continue;
827 sc.comp_unit = cu.get();
828 sc.module_sp = cu->GetModule();
829
830 // If we were asked to resolve line entries, add all entries to the line
831 // table that match the requested line (or all lines if `line` == 0).
832 if (resolve_scope & (eSymbolContextFunction | eSymbolContextBlock |
833 eSymbolContextLineEntry)) {
834 bool has_line_table = ParseCompileUnitLineTable(*sc.comp_unit, line);
835
836 if ((resolve_scope & eSymbolContextLineEntry) && !has_line_table) {
837 // The query asks for line entries, but we can't get them for the
838 // compile unit. This is not normal for `line` = 0. So just assert
839 // it.
840 assert(line && "Couldn't get all line entries!\n")((void)0);
841
842 // Current compiland does not have the requested line. Search next.
843 continue;
844 }
845
846 if (resolve_scope & (eSymbolContextFunction | eSymbolContextBlock)) {
847 if (!has_line_table)
848 continue;
849
850 auto *line_table = sc.comp_unit->GetLineTable();
851 lldbassert(line_table)lldb_private::lldb_assert(static_cast<bool>(line_table)
, "line_table", __FUNCTION__, "/usr/src/gnu/usr.bin/clang/liblldbPluginSymbolFile/../../../llvm/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp"
, 851)
;
852
853 uint32_t num_line_entries = line_table->GetSize();
854 // Skip the terminal line entry.
855 --num_line_entries;
856
857 // If `line `!= 0, see if we can resolve function for each line entry
858 // in the line table.
859 for (uint32_t line_idx = 0; line && line_idx < num_line_entries;
860 ++line_idx) {
861 if (!line_table->GetLineEntryAtIndex(line_idx, sc.line_entry))
862 continue;
863
864 auto file_vm_addr =
865 sc.line_entry.range.GetBaseAddress().GetFileAddress();
866 if (file_vm_addr == LLDB_INVALID_ADDRESS0xffffffffffffffffULL || file_vm_addr == 0)
867 continue;
868
869 auto symbol_up = m_session_up->findSymbolByAddress(
870 file_vm_addr, PDB_SymType::Function);
871 if (symbol_up) {
872 auto func_uid = symbol_up->getSymIndexId();
873 sc.function = sc.comp_unit->FindFunctionByUID(func_uid).get();
874 if (sc.function == nullptr) {
875 auto pdb_func = llvm::dyn_cast<PDBSymbolFunc>(symbol_up.get());
876 assert(pdb_func)((void)0);
877 sc.function = ParseCompileUnitFunctionForPDBFunc(*pdb_func,
878 *sc.comp_unit);
879 }
880 if (sc.function && (resolve_scope & eSymbolContextBlock)) {
881 Block &block = sc.function->GetBlock(true);
882 sc.block = block.FindBlockByID(sc.function->GetID());
883 }
884 }
885 sc_list.Append(sc);
886 }
887 } else if (has_line_table) {
888 // We can parse line table for the compile unit. But no query to
889 // resolve function or block. We append `sc` to the list anyway.
890 sc_list.Append(sc);
891 }
892 } else {
893 // No query for line entry, function or block. But we have a valid
894 // compile unit, append `sc` to the list.
895 sc_list.Append(sc);
896 }
897 }
898 }
899 return sc_list.GetSize() - old_size;
900}
901
902std::string SymbolFilePDB::GetMangledForPDBData(const PDBSymbolData &pdb_data) {
903 // Cache public names at first
904 if (m_public_names.empty())
905 if (auto result_up =
906 m_global_scope_up->findAllChildren(PDB_SymType::PublicSymbol))
907 while (auto symbol_up = result_up->getNext())
908 if (auto addr = symbol_up->getRawSymbol().getVirtualAddress())
909 m_public_names[addr] = symbol_up->getRawSymbol().getName();
910
911 // Look up the name in the cache
912 return m_public_names.lookup(pdb_data.getVirtualAddress());
913}
914
915VariableSP SymbolFilePDB::ParseVariableForPDBData(
916 const lldb_private::SymbolContext &sc,
917 const llvm::pdb::PDBSymbolData &pdb_data) {
918 VariableSP var_sp;
919 uint32_t var_uid = pdb_data.getSymIndexId();
920 auto result = m_variables.find(var_uid);
921 if (result != m_variables.end())
922 return result->second;
923
924 ValueType scope = eValueTypeInvalid;
925 bool is_static_member = false;
926 bool is_external = false;
927 bool is_artificial = false;
928
929 switch (pdb_data.getDataKind()) {
930 case PDB_DataKind::Global:
931 scope = eValueTypeVariableGlobal;
932 is_external = true;
933 break;
934 case PDB_DataKind::Local:
935 scope = eValueTypeVariableLocal;
936 break;
937 case PDB_DataKind::FileStatic:
938 scope = eValueTypeVariableStatic;
939 break;
940 case PDB_DataKind::StaticMember:
941 is_static_member = true;
942 scope = eValueTypeVariableStatic;
943 break;
944 case PDB_DataKind::Member:
945 scope = eValueTypeVariableStatic;
946 break;
947 case PDB_DataKind::Param:
948 scope = eValueTypeVariableArgument;
949 break;
950 case PDB_DataKind::Constant:
951 scope = eValueTypeConstResult;
952 break;
953 default:
954 break;
955 }
956
957 switch (pdb_data.getLocationType()) {
958 case PDB_LocType::TLS:
959 scope = eValueTypeVariableThreadLocal;
960 break;
961 case PDB_LocType::RegRel: {
962 // It is a `this` pointer.
963 if (pdb_data.getDataKind() == PDB_DataKind::ObjectPtr) {
964 scope = eValueTypeVariableArgument;
965 is_artificial = true;
966 }
967 } break;
968 default:
969 break;
970 }
971
972 Declaration decl;
973 if (!is_artificial && !pdb_data.isCompilerGenerated()) {
974 if (auto lines = pdb_data.getLineNumbers()) {
975 if (auto first_line = lines->getNext()) {
976 uint32_t src_file_id = first_line->getSourceFileId();
977 auto src_file = m_session_up->getSourceFileById(src_file_id);
978 if (src_file) {
979 FileSpec spec(src_file->getFileName());
980 decl.SetFile(spec);
981 decl.SetColumn(first_line->getColumnNumber());
982 decl.SetLine(first_line->getLineNumber());
983 }
984 }
985 }
986 }
987
988 Variable::RangeList ranges;
989 SymbolContextScope *context_scope = sc.comp_unit;
990 if (scope == eValueTypeVariableLocal || scope == eValueTypeVariableArgument) {
991 if (sc.function) {
992 Block &function_block = sc.function->GetBlock(true);
993 Block *block =
994 function_block.FindBlockByID(pdb_data.getLexicalParentId());
995 if (!block)
996 block = &function_block;
997
998 context_scope = block;
999
1000 for (size_t i = 0, num_ranges = block->GetNumRanges(); i < num_ranges;
1001 ++i) {
1002 AddressRange range;
1003 if (!block->GetRangeAtIndex(i, range))
1004 continue;
1005
1006 ranges.Append(range.GetBaseAddress().GetFileAddress(),
1007 range.GetByteSize());
1008 }
1009 }
1010 }
1011
1012 SymbolFileTypeSP type_sp =
1013 std::make_shared<SymbolFileType>(*this, pdb_data.getTypeId());
1014
1015 auto var_name = pdb_data.getName();
1016 auto mangled = GetMangledForPDBData(pdb_data);
1017 auto mangled_cstr = mangled.empty() ? nullptr : mangled.c_str();
1018
1019 bool is_constant;
1020 DWARFExpression location = ConvertPDBLocationToDWARFExpression(
1021 GetObjectFile()->GetModule(), pdb_data, ranges, is_constant);
1022
1023 var_sp = std::make_shared<Variable>(
1024 var_uid, var_name.c_str(), mangled_cstr, type_sp, scope, context_scope,
1025 ranges, &decl, location, is_external, is_artificial, is_constant,
1026 is_static_member);
1027
1028 m_variables.insert(std::make_pair(var_uid, var_sp));
1029 return var_sp;
1030}
1031
1032size_t
1033SymbolFilePDB::ParseVariables(const lldb_private::SymbolContext &sc,
1034 const llvm::pdb::PDBSymbol &pdb_symbol,
1035 lldb_private::VariableList *variable_list) {
1036 size_t num_added = 0;
1037
1038 if (auto pdb_data = llvm::dyn_cast<PDBSymbolData>(&pdb_symbol)) {
1039 VariableListSP local_variable_list_sp;
1040
1041 auto result = m_variables.find(pdb_data->getSymIndexId());
1042 if (result != m_variables.end()) {
1043 if (variable_list)
1044 variable_list->AddVariableIfUnique(result->second);
1045 } else {
1046 // Prepare right VariableList for this variable.
1047 if (auto lexical_parent = pdb_data->getLexicalParent()) {
1048 switch (lexical_parent->getSymTag()) {
1049 case PDB_SymType::Exe:
1050 assert(sc.comp_unit)((void)0);
1051 LLVM_FALLTHROUGH[[gnu::fallthrough]];
1052 case PDB_SymType::Compiland: {
1053 if (sc.comp_unit) {
1054 local_variable_list_sp = sc.comp_unit->GetVariableList(false);
1055 if (!local_variable_list_sp) {
1056 local_variable_list_sp = std::make_shared<VariableList>();
1057 sc.comp_unit->SetVariableList(local_variable_list_sp);
1058 }
1059 }
1060 } break;
1061 case PDB_SymType::Block:
1062 case PDB_SymType::Function: {
1063 if (sc.function) {
1064 Block *block = sc.function->GetBlock(true).FindBlockByID(
1065 lexical_parent->getSymIndexId());
1066 if (block) {
1067 local_variable_list_sp = block->GetBlockVariableList(false);
1068 if (!local_variable_list_sp) {
1069 local_variable_list_sp = std::make_shared<VariableList>();
1070 block->SetVariableList(local_variable_list_sp);
1071 }
1072 }
1073 }
1074 } break;
1075 default:
1076 break;
1077 }
1078 }
1079
1080 if (local_variable_list_sp) {
1081 if (auto var_sp = ParseVariableForPDBData(sc, *pdb_data)) {
1082 local_variable_list_sp->AddVariableIfUnique(var_sp);
1083 if (variable_list)
1084 variable_list->AddVariableIfUnique(var_sp);
1085 ++num_added;
1086 PDBASTParser *ast = GetPDBAstParser();
1087 if (ast)
1088 ast->GetDeclForSymbol(*pdb_data);
1089 }
1090 }
1091 }
1092 }
1093
1094 if (auto results = pdb_symbol.findAllChildren()) {
1095 while (auto result = results->getNext())
1096 num_added += ParseVariables(sc, *result, variable_list);
1097 }
1098
1099 return num_added;
1100}
1101
1102void SymbolFilePDB::FindGlobalVariables(
1103 lldb_private::ConstString name, const CompilerDeclContext &parent_decl_ctx,
1104 uint32_t max_matches, lldb_private::VariableList &variables) {
1105 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
1106 if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx))
1107 return;
1108 if (name.IsEmpty())
1109 return;
1110
1111 auto results = m_global_scope_up->findAllChildren<PDBSymbolData>();
1112 if (!results)
1113 return;
1114
1115 uint32_t matches = 0;
1116 size_t old_size = variables.GetSize();
1117 while (auto result = results->getNext()) {
1118 auto pdb_data = llvm::dyn_cast<PDBSymbolData>(result.get());
1119 if (max_matches > 0 && matches >= max_matches)
1120 break;
1121
1122 SymbolContext sc;
1123 sc.module_sp = m_objfile_sp->GetModule();
1124 lldbassert(sc.module_sp.get())lldb_private::lldb_assert(static_cast<bool>(sc.module_sp
.get()), "sc.module_sp.get()", __FUNCTION__, "/usr/src/gnu/usr.bin/clang/liblldbPluginSymbolFile/../../../llvm/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp"
, 1124)
;
1125
1126 if (!name.GetStringRef().equals(
1127 MSVCUndecoratedNameParser::DropScope(pdb_data->getName())))
1128 continue;
1129
1130 sc.comp_unit = ParseCompileUnitForUID(GetCompilandId(*pdb_data)).get();
1131 // FIXME: We are not able to determine the compile unit.
1132 if (sc.comp_unit == nullptr)
1133 continue;
1134
1135 if (parent_decl_ctx.IsValid() &&
1136 GetDeclContextContainingUID(result->getSymIndexId()) != parent_decl_ctx)
1137 continue;
1138
1139 ParseVariables(sc, *pdb_data, &variables);
1140 matches = variables.GetSize() - old_size;
1141 }
1142}
1143
1144void SymbolFilePDB::FindGlobalVariables(
1145 const lldb_private::RegularExpression &regex, uint32_t max_matches,
1146 lldb_private::VariableList &variables) {
1147 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
1148 if (!regex.IsValid())
1149 return;
1150 auto results = m_global_scope_up->findAllChildren<PDBSymbolData>();
1151 if (!results)
1152 return;
1153
1154 uint32_t matches = 0;
1155 size_t old_size = variables.GetSize();
1156 while (auto pdb_data = results->getNext()) {
1157 if (max_matches > 0 && matches >= max_matches)
1158 break;
1159
1160 auto var_name = pdb_data->getName();
1161 if (var_name.empty())
1162 continue;
1163 if (!regex.Execute(var_name))
1164 continue;
1165 SymbolContext sc;
1166 sc.module_sp = m_objfile_sp->GetModule();
1167 lldbassert(sc.module_sp.get())lldb_private::lldb_assert(static_cast<bool>(sc.module_sp
.get()), "sc.module_sp.get()", __FUNCTION__, "/usr/src/gnu/usr.bin/clang/liblldbPluginSymbolFile/../../../llvm/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp"
, 1167)
;
1168
1169 sc.comp_unit = ParseCompileUnitForUID(GetCompilandId(*pdb_data)).get();
1170 // FIXME: We are not able to determine the compile unit.
1171 if (sc.comp_unit == nullptr)
1172 continue;
1173
1174 ParseVariables(sc, *pdb_data, &variables);
1175 matches = variables.GetSize() - old_size;
1176 }
1177}
1178
1179bool SymbolFilePDB::ResolveFunction(const llvm::pdb::PDBSymbolFunc &pdb_func,
1180 bool include_inlines,
1181 lldb_private::SymbolContextList &sc_list) {
1182 lldb_private::SymbolContext sc;
1183 sc.comp_unit = ParseCompileUnitForUID(pdb_func.getCompilandId()).get();
1184 if (!sc.comp_unit)
1185 return false;
1186 sc.module_sp = sc.comp_unit->GetModule();
1187 sc.function = ParseCompileUnitFunctionForPDBFunc(pdb_func, *sc.comp_unit);
1188 if (!sc.function)
1189 return false;
1190
1191 sc_list.Append(sc);
1192 return true;
1193}
1194
1195bool SymbolFilePDB::ResolveFunction(uint32_t uid, bool include_inlines,
1196 lldb_private::SymbolContextList &sc_list) {
1197 auto pdb_func_up = m_session_up->getConcreteSymbolById<PDBSymbolFunc>(uid);
1198 if (!pdb_func_up && !(include_inlines && pdb_func_up->hasInlineAttribute()))
1199 return false;
1200 return ResolveFunction(*pdb_func_up, include_inlines, sc_list);
1201}
1202
1203void SymbolFilePDB::CacheFunctionNames() {
1204 if (!m_func_full_names.IsEmpty())
1205 return;
1206
1207 std::map<uint64_t, uint32_t> addr_ids;
1208
1209 if (auto results_up = m_global_scope_up->findAllChildren<PDBSymbolFunc>()) {
1210 while (auto pdb_func_up = results_up->getNext()) {
1211 if (pdb_func_up->isCompilerGenerated())
1212 continue;
1213
1214 auto name = pdb_func_up->getName();
1215 auto demangled_name = pdb_func_up->getUndecoratedName();
1216 if (name.empty() && demangled_name.empty())
1217 continue;
1218
1219 auto uid = pdb_func_up->getSymIndexId();
1220 if (!demangled_name.empty() && pdb_func_up->getVirtualAddress())
1221 addr_ids.insert(std::make_pair(pdb_func_up->getVirtualAddress(), uid));
1222
1223 if (auto parent = pdb_func_up->getClassParent()) {
1224
1225 // PDB have symbols for class/struct methods or static methods in Enum
1226 // Class. We won't bother to check if the parent is UDT or Enum here.
1227 m_func_method_names.Append(ConstString(name), uid);
1228
1229 // To search a method name, like NS::Class:MemberFunc, LLDB searches
1230 // its base name, i.e. MemberFunc by default. Since PDBSymbolFunc does
1231 // not have information of this, we extract base names and cache them
1232 // by our own effort.
1233 llvm::StringRef basename = MSVCUndecoratedNameParser::DropScope(name);
1234 if (!basename.empty())
1235 m_func_base_names.Append(ConstString(basename), uid);
1236 else {
1237 m_func_base_names.Append(ConstString(name), uid);
1238 }
1239
1240 if (!demangled_name.empty())
1241 m_func_full_names.Append(ConstString(demangled_name), uid);
1242
1243 } else {
1244 // Handle not-method symbols.
1245
1246 // The function name might contain namespace, or its lexical scope.
1247 llvm::StringRef basename = MSVCUndecoratedNameParser::DropScope(name);
1248 if (!basename.empty())
1249 m_func_base_names.Append(ConstString(basename), uid);
1250 else
1251 m_func_base_names.Append(ConstString(name), uid);
1252
1253 if (name == "main") {
1254 m_func_full_names.Append(ConstString(name), uid);
1255
1256 if (!demangled_name.empty() && name != demangled_name) {
1257 m_func_full_names.Append(ConstString(demangled_name), uid);
1258 m_func_base_names.Append(ConstString(demangled_name), uid);
1259 }
1260 } else if (!demangled_name.empty()) {
1261 m_func_full_names.Append(ConstString(demangled_name), uid);
1262 } else {
1263 m_func_full_names.Append(ConstString(name), uid);
1264 }
1265 }
1266 }
1267 }
1268
1269 if (auto results_up =
1270 m_global_scope_up->findAllChildren<PDBSymbolPublicSymbol>()) {
1271 while (auto pub_sym_up = results_up->getNext()) {
1272 if (!pub_sym_up->isFunction())
1273 continue;
1274 auto name = pub_sym_up->getName();
1275 if (name.empty())
1276 continue;
1277
1278 if (CPlusPlusLanguage::IsCPPMangledName(name.c_str())) {
1279 auto vm_addr = pub_sym_up->getVirtualAddress();
1280
1281 // PDB public symbol has mangled name for its associated function.
1282 if (vm_addr && addr_ids.find(vm_addr) != addr_ids.end()) {
1283 // Cache mangled name.
1284 m_func_full_names.Append(ConstString(name), addr_ids[vm_addr]);
1285 }
1286 }
1287 }
1288 }
1289 // Sort them before value searching is working properly
1290 m_func_full_names.Sort();
1291 m_func_full_names.SizeToFit();
1292 m_func_method_names.Sort();
1293 m_func_method_names.SizeToFit();
1294 m_func_base_names.Sort();
1295 m_func_base_names.SizeToFit();
1296}
1297
1298void SymbolFilePDB::FindFunctions(
1299 lldb_private::ConstString name,
1300 const lldb_private::CompilerDeclContext &parent_decl_ctx,
1301 FunctionNameType name_type_mask, bool include_inlines,
1302 lldb_private::SymbolContextList &sc_list) {
1303 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
1304 lldbassert((name_type_mask & eFunctionNameTypeAuto) == 0)lldb_private::lldb_assert(static_cast<bool>((name_type_mask
& eFunctionNameTypeAuto) == 0), "(name_type_mask & eFunctionNameTypeAuto) == 0"
, __FUNCTION__, "/usr/src/gnu/usr.bin/clang/liblldbPluginSymbolFile/../../../llvm/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp"
, 1304)
;
1305
1306 if (name_type_mask == eFunctionNameTypeNone)
1307 return;
1308 if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx))
1309 return;
1310 if (name.IsEmpty())
1311 return;
1312
1313 if (name_type_mask & eFunctionNameTypeFull ||
1314 name_type_mask & eFunctionNameTypeBase ||
1315 name_type_mask & eFunctionNameTypeMethod) {
1316 CacheFunctionNames();
1317
1318 std::set<uint32_t> resolved_ids;
1319 auto ResolveFn = [this, &name, parent_decl_ctx, include_inlines, &sc_list,
1320 &resolved_ids](UniqueCStringMap<uint32_t> &Names) {
1321 std::vector<uint32_t> ids;
1322 if (!Names.GetValues(name, ids))
1323 return;
1324
1325 for (uint32_t id : ids) {
1326 if (resolved_ids.find(id) != resolved_ids.end())
1327 continue;
1328
1329 if (parent_decl_ctx.IsValid() &&
1330 GetDeclContextContainingUID(id) != parent_decl_ctx)
1331 continue;
1332
1333 if (ResolveFunction(id, include_inlines, sc_list))
1334 resolved_ids.insert(id);
1335 }
1336 };
1337 if (name_type_mask & eFunctionNameTypeFull) {
1338 ResolveFn(m_func_full_names);
1339 ResolveFn(m_func_base_names);
1340 ResolveFn(m_func_method_names);
1341 }
1342 if (name_type_mask & eFunctionNameTypeBase)
1343 ResolveFn(m_func_base_names);
1344 if (name_type_mask & eFunctionNameTypeMethod)
1345 ResolveFn(m_func_method_names);
1346 }
1347}
1348
1349void SymbolFilePDB::FindFunctions(const lldb_private::RegularExpression &regex,
1350 bool include_inlines,
1351 lldb_private::SymbolContextList &sc_list) {
1352 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
1353 if (!regex.IsValid())
1354 return;
1355
1356 CacheFunctionNames();
1357
1358 std::set<uint32_t> resolved_ids;
1359 auto ResolveFn = [&regex, include_inlines, &sc_list, &resolved_ids,
1360 this](UniqueCStringMap<uint32_t> &Names) {
1361 std::vector<uint32_t> ids;
1362 if (Names.GetValues(regex, ids)) {
1363 for (auto id : ids) {
1364 if (resolved_ids.find(id) == resolved_ids.end())
1365 if (ResolveFunction(id, include_inlines, sc_list))
1366 resolved_ids.insert(id);
1367 }
1368 }
1369 };
1370 ResolveFn(m_func_full_names);
1371 ResolveFn(m_func_base_names);
1372}
1373
1374void SymbolFilePDB::GetMangledNamesForFunction(
1375 const std::string &scope_qualified_name,
1376 std::vector<lldb_private::ConstString> &mangled_names) {}
1377
1378void SymbolFilePDB::AddSymbols(lldb_private::Symtab &symtab) {
1379 std::set<lldb::addr_t> sym_addresses;
1380 for (size_t i = 0; i < symtab.GetNumSymbols(); i++)
1381 sym_addresses.insert(symtab.SymbolAtIndex(i)->GetFileAddress());
1382
1383 auto results = m_global_scope_up->findAllChildren<PDBSymbolPublicSymbol>();
1384 if (!results)
1385 return;
1386
1387 auto section_list = m_objfile_sp->GetSectionList();
1388 if (!section_list)
1389 return;
1390
1391 while (auto pub_symbol = results->getNext()) {
1392 auto section_id = pub_symbol->getAddressSection();
1393
1394 auto section = section_list->FindSectionByID(section_id);
1395 if (!section)
1396 continue;
1397
1398 auto offset = pub_symbol->getAddressOffset();
1399
1400 auto file_addr = section->GetFileAddress() + offset;
1401 if (sym_addresses.find(file_addr) != sym_addresses.end())
1402 continue;
1403 sym_addresses.insert(file_addr);
1404
1405 auto size = pub_symbol->getLength();
1406 symtab.AddSymbol(
1407 Symbol(pub_symbol->getSymIndexId(), // symID
1408 pub_symbol->getName().c_str(), // name
1409 pub_symbol->isCode() ? eSymbolTypeCode : eSymbolTypeData, // type
1410 true, // external
1411 false, // is_debug
1412 false, // is_trampoline
1413 false, // is_artificial
1414 section, // section_sp
1415 offset, // value
1416 size, // size
1417 size != 0, // size_is_valid
1418 false, // contains_linker_annotations
1419 0 // flags
1420 ));
1421 }
1422
1423 symtab.CalculateSymbolSizes();
1424 symtab.Finalize();
1425}
1426
1427void SymbolFilePDB::FindTypes(
1428 lldb_private::ConstString name, const CompilerDeclContext &parent_decl_ctx,
1429 uint32_t max_matches,
1430 llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
1431 lldb_private::TypeMap &types) {
1432 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
1433 if (!name)
1434 return;
1435 if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx))
1436 return;
1437
1438 searched_symbol_files.clear();
1439 searched_symbol_files.insert(this);
1440
1441 // There is an assumption 'name' is not a regex
1442 FindTypesByName(name.GetStringRef(), parent_decl_ctx, max_matches, types);
1443}
1444
1445void SymbolFilePDB::DumpClangAST(Stream &s) {
1446 auto type_system_or_err =
1447 GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);
1448 if (auto err = type_system_or_err.takeError()) {
1449 LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS),do { ::lldb_private::Log *log_private = (lldb_private::GetLogIfAnyCategoriesSet
((1u << 20))); ::llvm::Error error_private = (std::move
(err)); if (log_private && error_private) { log_private
->FormatError(::std::move(error_private), "/usr/src/gnu/usr.bin/clang/liblldbPluginSymbolFile/../../../llvm/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp"
, __func__, "Unable to dump ClangAST"); } else ::llvm::consumeError
(::std::move(error_private)); } while (0)
1450 std::move(err), "Unable to dump ClangAST")do { ::lldb_private::Log *log_private = (lldb_private::GetLogIfAnyCategoriesSet
((1u << 20))); ::llvm::Error error_private = (std::move
(err)); if (log_private && error_private) { log_private
->FormatError(::std::move(error_private), "/usr/src/gnu/usr.bin/clang/liblldbPluginSymbolFile/../../../llvm/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp"
, __func__, "Unable to dump ClangAST"); } else ::llvm::consumeError
(::std::move(error_private)); } while (0)
;
1451 return;
1452 }
1453
1454 auto *clang_type_system =
1455 llvm::dyn_cast_or_null<TypeSystemClang>(&type_system_or_err.get());
1456 if (!clang_type_system)
1457 return;
1458 clang_type_system->Dump(s);
1459}
1460
1461void SymbolFilePDB::FindTypesByRegex(
1462 const lldb_private::RegularExpression &regex, uint32_t max_matches,
1463 lldb_private::TypeMap &types) {
1464 // When searching by regex, we need to go out of our way to limit the search
1465 // space as much as possible since this searches EVERYTHING in the PDB,
1466 // manually doing regex comparisons. PDB library isn't optimized for regex
1467 // searches or searches across multiple symbol types at the same time, so the
1468 // best we can do is to search enums, then typedefs, then classes one by one,
1469 // and do a regex comparison against each of them.
1470 PDB_SymType tags_to_search[] = {PDB_SymType::Enum, PDB_SymType::Typedef,
1471 PDB_SymType::UDT};
1472 std::unique_ptr<IPDBEnumSymbols> results;
1473
1474 uint32_t matches = 0;
1475
1476 for (auto tag : tags_to_search) {
1477 results = m_global_scope_up->findAllChildren(tag);
1478 if (!results)
1479 continue;
1480
1481 while (auto result = results->getNext()) {
1482 if (max_matches > 0 && matches >= max_matches)
1483 break;
1484
1485 std::string type_name;
1486 if (auto enum_type = llvm::dyn_cast<PDBSymbolTypeEnum>(result.get()))
1487 type_name = enum_type->getName();
1488 else if (auto typedef_type =
1489 llvm::dyn_cast<PDBSymbolTypeTypedef>(result.get()))
1490 type_name = typedef_type->getName();
1491 else if (auto class_type = llvm::dyn_cast<PDBSymbolTypeUDT>(result.get()))
1492 type_name = class_type->getName();
1493 else {
1494 // We're looking only for types that have names. Skip symbols, as well
1495 // as unnamed types such as arrays, pointers, etc.
1496 continue;
1497 }
1498
1499 if (!regex.Execute(type_name))
1500 continue;
1501
1502 // This should cause the type to get cached and stored in the `m_types`
1503 // lookup.
1504 if (!ResolveTypeUID(result->getSymIndexId()))
1505 continue;
1506
1507 auto iter = m_types.find(result->getSymIndexId());
1508 if (iter == m_types.end())
1509 continue;
1510 types.Insert(iter->second);
1511 ++matches;
1512 }
1513 }
1514}
1515
1516void SymbolFilePDB::FindTypesByName(
1517 llvm::StringRef name,
1518 const lldb_private::CompilerDeclContext &parent_decl_ctx,
1519 uint32_t max_matches, lldb_private::TypeMap &types) {
1520 std::unique_ptr<IPDBEnumSymbols> results;
1521 if (name.empty())
1522 return;
1523 results = m_global_scope_up->findAllChildren(PDB_SymType::None);
1524 if (!results)
1525 return;
1526
1527 uint32_t matches = 0;
1528
1529 while (auto result = results->getNext()) {
1530 if (max_matches > 0 && matches >= max_matches)
1531 break;
1532
1533 if (MSVCUndecoratedNameParser::DropScope(
1534 result->getRawSymbol().getName()) != name)
1535 continue;
1536
1537 switch (result->getSymTag()) {
1538 case PDB_SymType::Enum:
1539 case PDB_SymType::UDT:
1540 case PDB_SymType::Typedef:
1541 break;
1542 default:
1543 // We're looking only for types that have names. Skip symbols, as well
1544 // as unnamed types such as arrays, pointers, etc.
1545 continue;
1546 }
1547
1548 // This should cause the type to get cached and stored in the `m_types`
1549 // lookup.
1550 if (!ResolveTypeUID(result->getSymIndexId()))
1551 continue;
1552
1553 if (parent_decl_ctx.IsValid() &&
1554 GetDeclContextContainingUID(result->getSymIndexId()) != parent_decl_ctx)
1555 continue;
1556
1557 auto iter = m_types.find(result->getSymIndexId());
1558 if (iter == m_types.end())
1559 continue;
1560 types.Insert(iter->second);
1561 ++matches;
1562 }
1563}
1564
1565void SymbolFilePDB::FindTypes(
1566 llvm::ArrayRef<CompilerContext> pattern, LanguageSet languages,
1567 llvm::DenseSet<SymbolFile *> &searched_symbol_files,
1568 lldb_private::TypeMap &types) {}
1569
1570void SymbolFilePDB::GetTypesForPDBSymbol(const llvm::pdb::PDBSymbol &pdb_symbol,
1571 uint32_t type_mask,
1572 TypeCollection &type_collection) {
1573 bool can_parse = false;
1574 switch (pdb_symbol.getSymTag()) {
1575 case PDB_SymType::ArrayType:
1576 can_parse = ((type_mask & eTypeClassArray) != 0);
1577 break;
1578 case PDB_SymType::BuiltinType:
1579 can_parse = ((type_mask & eTypeClassBuiltin) != 0);
1580 break;
1581 case PDB_SymType::Enum:
1582 can_parse = ((type_mask & eTypeClassEnumeration) != 0);
1583 break;
1584 case PDB_SymType::Function:
1585 case PDB_SymType::FunctionSig:
1586 can_parse = ((type_mask & eTypeClassFunction) != 0);
1587 break;
1588 case PDB_SymType::PointerType:
1589 can_parse = ((type_mask & (eTypeClassPointer | eTypeClassBlockPointer |
1590 eTypeClassMemberPointer)) != 0);
1591 break;
1592 case PDB_SymType::Typedef:
1593 can_parse = ((type_mask & eTypeClassTypedef) != 0);
1594 break;
1595 case PDB_SymType::UDT: {
1596 auto *udt = llvm::dyn_cast<PDBSymbolTypeUDT>(&pdb_symbol);
1597 assert(udt)((void)0);
1598 can_parse = (udt->getUdtKind() != PDB_UdtType::Interface &&
1599 ((type_mask & (eTypeClassClass | eTypeClassStruct |
1600 eTypeClassUnion)) != 0));
1601 } break;
1602 default:
1603 break;
1604 }
1605
1606 if (can_parse) {
1607 if (auto *type = ResolveTypeUID(pdb_symbol.getSymIndexId())) {
1608 auto result =
1609 std::find(type_collection.begin(), type_collection.end(), type);
1610 if (result == type_collection.end())
1611 type_collection.push_back(type);
1612 }
1613 }
1614
1615 auto results_up = pdb_symbol.findAllChildren();
1616 while (auto symbol_up = results_up->getNext())
1617 GetTypesForPDBSymbol(*symbol_up, type_mask, type_collection);
1618}
1619
1620void SymbolFilePDB::GetTypes(lldb_private::SymbolContextScope *sc_scope,
1621 TypeClass type_mask,
1622 lldb_private::TypeList &type_list) {
1623 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
1624 TypeCollection type_collection;
1625 CompileUnit *cu =
1626 sc_scope ? sc_scope->CalculateSymbolContextCompileUnit() : nullptr;
1627 if (cu) {
1628 auto compiland_up = GetPDBCompilandByUID(cu->GetID());
1629 if (!compiland_up)
1630 return;
1631 GetTypesForPDBSymbol(*compiland_up, type_mask, type_collection);
1632 } else {
1633 for (uint32_t cu_idx = 0; cu_idx < GetNumCompileUnits(); ++cu_idx) {
1634 auto cu_sp = ParseCompileUnitAtIndex(cu_idx);
1635 if (cu_sp) {
1636 if (auto compiland_up = GetPDBCompilandByUID(cu_sp->GetID()))
1637 GetTypesForPDBSymbol(*compiland_up, type_mask, type_collection);
1638 }
1639 }
1640 }
1641
1642 for (auto type : type_collection) {
1643 type->GetForwardCompilerType();
1644 type_list.Insert(type->shared_from_this());
1645 }
1646}
1647
1648llvm::Expected<lldb_private::TypeSystem &>
1649SymbolFilePDB::GetTypeSystemForLanguage(lldb::LanguageType language) {
1650 auto type_system_or_err =
1651 m_objfile_sp->GetModule()->GetTypeSystemForLanguage(language);
1652 if (type_system_or_err) {
1653 type_system_or_err->SetSymbolFile(this);
1654 }
1655 return type_system_or_err;
1656}
1657
1658PDBASTParser *SymbolFilePDB::GetPDBAstParser() {
1659 auto type_system_or_err =
1660 GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);
1661 if (auto err = type_system_or_err.takeError()) {
1662 LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS),do { ::lldb_private::Log *log_private = (lldb_private::GetLogIfAnyCategoriesSet
((1u << 20))); ::llvm::Error error_private = (std::move
(err)); if (log_private && error_private) { log_private
->FormatError(::std::move(error_private), "/usr/src/gnu/usr.bin/clang/liblldbPluginSymbolFile/../../../llvm/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp"
, __func__, "Unable to get PDB AST parser"); } else ::llvm::consumeError
(::std::move(error_private)); } while (0)
1663 std::move(err), "Unable to get PDB AST parser")do { ::lldb_private::Log *log_private = (lldb_private::GetLogIfAnyCategoriesSet
((1u << 20))); ::llvm::Error error_private = (std::move
(err)); if (log_private && error_private) { log_private
->FormatError(::std::move(error_private), "/usr/src/gnu/usr.bin/clang/liblldbPluginSymbolFile/../../../llvm/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp"
, __func__, "Unable to get PDB AST parser"); } else ::llvm::consumeError
(::std::move(error_private)); } while (0)
;
1664 return nullptr;
1665 }
1666
1667 auto *clang_type_system =
1668 llvm::dyn_cast_or_null<TypeSystemClang>(&type_system_or_err.get());
1669 if (!clang_type_system)
1670 return nullptr;
1671
1672 return clang_type_system->GetPDBParser();
1673}
1674
1675lldb_private::CompilerDeclContext
1676SymbolFilePDB::FindNamespace(lldb_private::ConstString name,
1677 const CompilerDeclContext &parent_decl_ctx) {
1678 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
1679 auto type_system_or_err =
1680 GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);
1681 if (auto err = type_system_or_err.takeError()) {
1682 LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS),do { ::lldb_private::Log *log_private = (lldb_private::GetLogIfAnyCategoriesSet
((1u << 20))); ::llvm::Error error_private = (std::move
(err)); if (log_private && error_private) { log_private
->FormatError(::std::move(error_private), "/usr/src/gnu/usr.bin/clang/liblldbPluginSymbolFile/../../../llvm/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp"
, __func__, "Unable to find namespace {}", name.AsCString());
} else ::llvm::consumeError(::std::move(error_private)); } while
(0)
1683 std::move(err), "Unable to find namespace {}",do { ::lldb_private::Log *log_private = (lldb_private::GetLogIfAnyCategoriesSet
((1u << 20))); ::llvm::Error error_private = (std::move
(err)); if (log_private && error_private) { log_private
->FormatError(::std::move(error_private), "/usr/src/gnu/usr.bin/clang/liblldbPluginSymbolFile/../../../llvm/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp"
, __func__, "Unable to find namespace {}", name.AsCString());
} else ::llvm::consumeError(::std::move(error_private)); } while
(0)
1684 name.AsCString())do { ::lldb_private::Log *log_private = (lldb_private::GetLogIfAnyCategoriesSet
((1u << 20))); ::llvm::Error error_private = (std::move
(err)); if (log_private && error_private) { log_private
->FormatError(::std::move(error_private), "/usr/src/gnu/usr.bin/clang/liblldbPluginSymbolFile/../../../llvm/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp"
, __func__, "Unable to find namespace {}", name.AsCString());
} else ::llvm::consumeError(::std::move(error_private)); } while
(0)
;
1685 return CompilerDeclContext();
1686 }
1687
1688 auto *clang_type_system =
1689 llvm::dyn_cast_or_null<TypeSystemClang>(&type_system_or_err.get());
1690 if (!clang_type_system)
1691 return CompilerDeclContext();
1692
1693 PDBASTParser *pdb = clang_type_system->GetPDBParser();
1694 if (!pdb)
1695 return CompilerDeclContext();
1696
1697 clang::DeclContext *decl_context = nullptr;
1698 if (parent_decl_ctx)
1699 decl_context = static_cast<clang::DeclContext *>(
1700 parent_decl_ctx.GetOpaqueDeclContext());
1701
1702 auto namespace_decl =
1703 pdb->FindNamespaceDecl(decl_context, name.GetStringRef());
1704 if (!namespace_decl)
1705 return CompilerDeclContext();
1706
1707 return clang_type_system->CreateDeclContext(namespace_decl);
1708}
1709
1710lldb_private::ConstString SymbolFilePDB::GetPluginName() {
1711 static ConstString g_name("pdb");
1712 return g_name;
1713}
1714
1715uint32_t SymbolFilePDB::GetPluginVersion() { return 1; }
1716
1717IPDBSession &SymbolFilePDB::GetPDBSession() { return *m_session_up; }
1718
1719const IPDBSession &SymbolFilePDB::GetPDBSession() const {
1720 return *m_session_up;
1721}
1722
1723lldb::CompUnitSP SymbolFilePDB::ParseCompileUnitForUID(uint32_t id,
1724 uint32_t index) {
1725 auto found_cu = m_comp_units.find(id);
1726 if (found_cu != m_comp_units.end())
1727 return found_cu->second;
1728
1729 auto compiland_up = GetPDBCompilandByUID(id);
1730 if (!compiland_up)
1731 return CompUnitSP();
1732
1733 lldb::LanguageType lang;
1734 auto details = compiland_up->findOneChild<PDBSymbolCompilandDetails>();
1735 if (!details)
1736 lang = lldb::eLanguageTypeC_plus_plus;
1737 else
1738 lang = TranslateLanguage(details->getLanguage());
1739
1740 if (lang == lldb::LanguageType::eLanguageTypeUnknown)
1741 return CompUnitSP();
1742
1743 std::string path = compiland_up->getSourceFileFullPath();
1744 if (path.empty())
1745 return CompUnitSP();
1746
1747 // Don't support optimized code for now, DebugInfoPDB does not return this
1748 // information.
1749 LazyBool optimized = eLazyBoolNo;
1750 auto cu_sp = std::make_shared<CompileUnit>(m_objfile_sp->GetModule(), nullptr,
1751 path.c_str(), id, lang, optimized);
1752
1753 if (!cu_sp)
1754 return CompUnitSP();
1755
1756 m_comp_units.insert(std::make_pair(id, cu_sp));
1757 if (index == UINT32_MAX0xffffffffU)
1758 GetCompileUnitIndex(*compiland_up, index);
1759 lldbassert(index != UINT32_MAX)lldb_private::lldb_assert(static_cast<bool>(index != 0xffffffffU
), "index != UINT32_MAX", __FUNCTION__, "/usr/src/gnu/usr.bin/clang/liblldbPluginSymbolFile/../../../llvm/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp"
, 1759)
;
1760 SetCompileUnitAtIndex(index, cu_sp);
1761 return cu_sp;
1762}
1763
1764bool SymbolFilePDB::ParseCompileUnitLineTable(CompileUnit &comp_unit,
1765 uint32_t match_line) {
1766 auto compiland_up = GetPDBCompilandByUID(comp_unit.GetID());
1767 if (!compiland_up)
1768 return false;
1769
1770 // LineEntry needs the *index* of the file into the list of support files
1771 // returned by ParseCompileUnitSupportFiles. But the underlying SDK gives us
1772 // a globally unique idenfitifier in the namespace of the PDB. So, we have
1773 // to do a mapping so that we can hand out indices.
1774 llvm::DenseMap<uint32_t, uint32_t> index_map;
1775 BuildSupportFileIdToSupportFileIndexMap(*compiland_up, index_map);
1776 auto line_table = std::make_unique<LineTable>(&comp_unit);
1777
1778 // Find contributions to `compiland` from all source and header files.
1779 auto files = m_session_up->getSourceFilesForCompiland(*compiland_up);
1780 if (!files)
1781 return false;
1782
1783 // For each source and header file, create a LineSequence for contributions
1784 // to the compiland from that file, and add the sequence.
1785 while (auto file = files->getNext()) {
1786 std::unique_ptr<LineSequence> sequence(
1787 line_table->CreateLineSequenceContainer());
1788 auto lines = m_session_up->findLineNumbers(*compiland_up, *file);
1789 if (!lines)
1790 continue;
1791 int entry_count = lines->getChildCount();
1792
1793 uint64_t prev_addr;
1794 uint32_t prev_length;
1795 uint32_t prev_line;
1796 uint32_t prev_source_idx;
1797
1798 for (int i = 0; i < entry_count; ++i) {
1799 auto line = lines->getChildAtIndex(i);
1800
1801 uint64_t lno = line->getLineNumber();
1802 uint64_t addr = line->getVirtualAddress();
1803 uint32_t length = line->getLength();
1804 uint32_t source_id = line->getSourceFileId();
1805 uint32_t col = line->getColumnNumber();
1806 uint32_t source_idx = index_map[source_id];
1807
1808 // There was a gap between the current entry and the previous entry if
1809 // the addresses don't perfectly line up.
1810 bool is_gap = (i > 0) && (prev_addr + prev_length < addr);
1811
1812 // Before inserting the current entry, insert a terminal entry at the end
1813 // of the previous entry's address range if the current entry resulted in
1814 // a gap from the previous entry.
1815 if (is_gap && ShouldAddLine(match_line, prev_line, prev_length)) {
1816 line_table->AppendLineEntryToSequence(
1817 sequence.get(), prev_addr + prev_length, prev_line, 0,
1818 prev_source_idx, false, false, false, false, true);
1819
1820 line_table->InsertSequence(sequence.get());
1821 sequence = line_table->CreateLineSequenceContainer();
1822 }
1823
1824 if (ShouldAddLine(match_line, lno, length)) {
1825 bool is_statement = line->isStatement();
1826 bool is_prologue = false;
1827 bool is_epilogue = false;
1828 auto func =
1829 m_session_up->findSymbolByAddress(addr, PDB_SymType::Function);
1830 if (func) {
1831 auto prologue = func->findOneChild<PDBSymbolFuncDebugStart>();
1832 if (prologue)
1833 is_prologue = (addr == prologue->getVirtualAddress());
1834
1835 auto epilogue = func->findOneChild<PDBSymbolFuncDebugEnd>();
1836 if (epilogue)
1837 is_epilogue = (addr == epilogue->getVirtualAddress());
1838 }
1839
1840 line_table->AppendLineEntryToSequence(sequence.get(), addr, lno, col,
1841 source_idx, is_statement, false,
1842 is_prologue, is_epilogue, false);
1843 }
1844
1845 prev_addr = addr;
1846 prev_length = length;
1847 prev_line = lno;
1848 prev_source_idx = source_idx;
1849 }
1850
1851 if (entry_count > 0 && ShouldAddLine(match_line, prev_line, prev_length)) {
1852 // The end is always a terminal entry, so insert it regardless.
1853 line_table->AppendLineEntryToSequence(
1854 sequence.get(), prev_addr + prev_length, prev_line, 0,
1855 prev_source_idx, false, false, false, false, true);
1856 }
1857
1858 line_table->InsertSequence(sequence.get());
1859 }
1860
1861 if (line_table->GetSize()) {
1862 comp_unit.SetLineTable(line_table.release());
1863 return true;
1864 }
1865 return false;
1866}
1867
1868void SymbolFilePDB::BuildSupportFileIdToSupportFileIndexMap(
1869 const PDBSymbolCompiland &compiland,
1870 llvm::DenseMap<uint32_t, uint32_t> &index_map) const {
1871 // This is a hack, but we need to convert the source id into an index into
1872 // the support files array. We don't want to do path comparisons to avoid
1873 // basename / full path issues that may or may not even be a problem, so we
1874 // use the globally unique source file identifiers. Ideally we could use the
1875 // global identifiers everywhere, but LineEntry currently assumes indices.
1876 auto source_files = m_session_up->getSourceFilesForCompiland(compiland);
1877 if (!source_files)
1878 return;
1879
1880 int index = 0;
1881 while (auto file = source_files->getNext()) {
1882 uint32_t source_id = file->getUniqueId();
1883 index_map[source_id] = index++;
1884 }
1885}
1886
1887lldb::CompUnitSP SymbolFilePDB::GetCompileUnitContainsAddress(
1888 const lldb_private::Address &so_addr) {
1889 lldb::addr_t file_vm_addr = so_addr.GetFileAddress();
1890 if (file_vm_addr == LLDB_INVALID_ADDRESS0xffffffffffffffffULL || file_vm_addr == 0)
1891 return nullptr;
1892
1893 // If it is a PDB function's vm addr, this is the first sure bet.
1894 if (auto lines =
1895 m_session_up->findLineNumbersByAddress(file_vm_addr, /*Length=*/1)) {
1896 if (auto first_line = lines->getNext())
1897 return ParseCompileUnitForUID(first_line->getCompilandId());
1898 }
1899
1900 // Otherwise we resort to section contributions.
1901 if (auto sec_contribs = m_session_up->getSectionContribs()) {
1902 while (auto section = sec_contribs->getNext()) {
1903 auto va = section->getVirtualAddress();
1904 if (file_vm_addr >= va && file_vm_addr < va + section->getLength())
1905 return ParseCompileUnitForUID(section->getCompilandId());
1906 }
1907 }
1908 return nullptr;
1909}
1910
1911Mangled
1912SymbolFilePDB::GetMangledForPDBFunc(const llvm::pdb::PDBSymbolFunc &pdb_func) {
1913 Mangled mangled;
1914 auto func_name = pdb_func.getName();
1915 auto func_undecorated_name = pdb_func.getUndecoratedName();
1916 std::string func_decorated_name;
1917
1918 // Seek from public symbols for non-static function's decorated name if any.
1919 // For static functions, they don't have undecorated names and aren't exposed
1920 // in Public Symbols either.
1921 if (!func_undecorated_name.empty()) {
1922 auto result_up = m_global_scope_up->findChildren(
1923 PDB_SymType::PublicSymbol, func_undecorated_name,
1924 PDB_NameSearchFlags::NS_UndecoratedName);
1925 if (result_up) {
1926 while (auto symbol_up = result_up->getNext()) {
1927 // For a public symbol, it is unique.
1928 lldbassert(result_up->getChildCount() == 1)lldb_private::lldb_assert(static_cast<bool>(result_up->
getChildCount() == 1), "result_up->getChildCount() == 1", __FUNCTION__
, "/usr/src/gnu/usr.bin/clang/liblldbPluginSymbolFile/../../../llvm/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp"
, 1928)
;
1929 if (auto *pdb_public_sym =
1930 llvm::dyn_cast_or_null<PDBSymbolPublicSymbol>(
1931 symbol_up.get())) {
1932 if (pdb_public_sym->isFunction()) {
1933 func_decorated_name = pdb_public_sym->getName();
1934 break;
1935 }
1936 }
1937 }
1938 }
1939 }
1940 if (!func_decorated_name.empty()) {
1941 mangled.SetMangledName(ConstString(func_decorated_name));
1942
1943 // For MSVC, format of C funciton's decorated name depends on calling
1944 // convention. Unfortunately none of the format is recognized by current
1945 // LLDB. For example, `_purecall` is a __cdecl C function. From PDB,
1946 // `__purecall` is retrieved as both its decorated and undecorated name
1947 // (using PDBSymbolFunc::getUndecoratedName method). However `__purecall`
1948 // string is not treated as mangled in LLDB (neither `?` nor `_Z` prefix).
1949 // Mangled::GetDemangledName method will fail internally and caches an
1950 // empty string as its undecorated name. So we will face a contradiction
1951 // here for the same symbol:
1952 // non-empty undecorated name from PDB
1953 // empty undecorated name from LLDB
1954 if (!func_undecorated_name.empty() && mangled.GetDemangledName().IsEmpty())
1955 mangled.SetDemangledName(ConstString(func_undecorated_name));
1956
1957 // LLDB uses several flags to control how a C++ decorated name is
1958 // undecorated for MSVC. See `safeUndecorateName` in Class Mangled. So the
1959 // yielded name could be different from what we retrieve from
1960 // PDB source unless we also apply same flags in getting undecorated
1961 // name through PDBSymbolFunc::getUndecoratedNameEx method.
1962 if (!func_undecorated_name.empty() &&
1963 mangled.GetDemangledName() != ConstString(func_undecorated_name))
1964 mangled.SetDemangledName(ConstString(func_undecorated_name));
1965 } else if (!func_undecorated_name.empty()) {
1966 mangled.SetDemangledName(ConstString(func_undecorated_name));
1967 } else if (!func_name.empty())
1968 mangled.SetValue(ConstString(func_name), false);
1969
1970 return mangled;
1971}
1972
1973bool SymbolFilePDB::DeclContextMatchesThisSymbolFile(
1974 const lldb_private::CompilerDeclContext &decl_ctx) {
1975 if (!decl_ctx.IsValid())
1976 return true;
1977
1978 TypeSystem *decl_ctx_type_system = decl_ctx.GetTypeSystem();
1979 if (!decl_ctx_type_system)
1980 return false;
1981 auto type_system_or_err = GetTypeSystemForLanguage(
1982 decl_ctx_type_system->GetMinimumLanguage(nullptr));
1983 if (auto err = type_system_or_err.takeError()) {
1984 LLDB_LOG_ERROR(do { ::lldb_private::Log *log_private = (lldb_private::GetLogIfAnyCategoriesSet
((1u << 20))); ::llvm::Error error_private = (std::move
(err)); if (log_private && error_private) { log_private
->FormatError(::std::move(error_private), "/usr/src/gnu/usr.bin/clang/liblldbPluginSymbolFile/../../../llvm/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp"
, __func__, "Unable to determine if DeclContext matches this symbol file"
); } else ::llvm::consumeError(::std::move(error_private)); }
while (0)
1985 lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS),do { ::lldb_private::Log *log_private = (lldb_private::GetLogIfAnyCategoriesSet
((1u << 20))); ::llvm::Error error_private = (std::move
(err)); if (log_private && error_private) { log_private
->FormatError(::std::move(error_private), "/usr/src/gnu/usr.bin/clang/liblldbPluginSymbolFile/../../../llvm/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp"
, __func__, "Unable to determine if DeclContext matches this symbol file"
); } else ::llvm::consumeError(::std::move(error_private)); }
while (0)
1986 std::move(err),do { ::lldb_private::Log *log_private = (lldb_private::GetLogIfAnyCategoriesSet
((1u << 20))); ::llvm::Error error_private = (std::move
(err)); if (log_private && error_private) { log_private
->FormatError(::std::move(error_private), "/usr/src/gnu/usr.bin/clang/liblldbPluginSymbolFile/../../../llvm/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp"
, __func__, "Unable to determine if DeclContext matches this symbol file"
); } else ::llvm::consumeError(::std::move(error_private)); }
while (0)
1987 "Unable to determine if DeclContext matches this symbol file")do { ::lldb_private::Log *log_private = (lldb_private::GetLogIfAnyCategoriesSet
((1u << 20))); ::llvm::Error error_private = (std::move
(err)); if (log_private && error_private) { log_private
->FormatError(::std::move(error_private), "/usr/src/gnu/usr.bin/clang/liblldbPluginSymbolFile/../../../llvm/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp"
, __func__, "Unable to determine if DeclContext matches this symbol file"
); } else ::llvm::consumeError(::std::move(error_private)); }
while (0)
;
1988 return false;
1989 }
1990
1991 if (decl_ctx_type_system == &type_system_or_err.get())
1992 return true; // The type systems match, return true
1993
1994 return false;
1995}
1996
1997uint32_t SymbolFilePDB::GetCompilandId(const llvm::pdb::PDBSymbolData &data) {
1998 static const auto pred_upper = [](uint32_t lhs, SecContribInfo rhs) {
1999 return lhs < rhs.Offset;
2000 };
2001
2002 // Cache section contributions
2003 if (m_sec_contribs.empty()) {
2004 if (auto SecContribs = m_session_up->getSectionContribs()) {
2005 while (auto SectionContrib = SecContribs->getNext()) {
2006 auto comp_id = SectionContrib->getCompilandId();
2007 if (!comp_id)
2008 continue;
2009
2010 auto sec = SectionContrib->getAddressSection();
2011 auto &sec_cs = m_sec_contribs[sec];
2012
2013 auto offset = SectionContrib->getAddressOffset();
2014 auto it =
2015 std::upper_bound(sec_cs.begin(), sec_cs.end(), offset, pred_upper);
2016
2017 auto size = SectionContrib->getLength();
2018 sec_cs.insert(it, {offset, size, comp_id});
2019 }
2020 }
2021 }
2022
2023 // Check by line number
2024 if (auto Lines = data.getLineNumbers()) {
2025 if (auto FirstLine = Lines->getNext())
2026 return FirstLine->getCompilandId();
2027 }
2028
2029 // Retrieve section + offset
2030 uint32_t DataSection = data.getAddressSection();
2031 uint32_t DataOffset = data.getAddressOffset();
2032 if (DataSection == 0) {
2033 if (auto RVA = data.getRelativeVirtualAddress())
2034 m_session_up->addressForRVA(RVA, DataSection, DataOffset);
2035 }
2036
2037 if (DataSection) {
2038 // Search by section contributions
2039 auto &sec_cs = m_sec_contribs[DataSection];
2040 auto it =
2041 std::upper_bound(sec_cs.begin(), sec_cs.end(), DataOffset, pred_upper);
2042 if (it != sec_cs.begin()) {
2043 --it;
2044 if (DataOffset < it->Offset + it->Size)
2045 return it->CompilandId;
2046 }
2047 } else {
2048 // Search in lexical tree
2049 auto LexParentId = data.getLexicalParentId();
2050 while (auto LexParent = m_session_up->getSymbolById(LexParentId)) {
2051 if (LexParent->getSymTag() == PDB_SymType::Exe)
2052 break;
2053 if (LexParent->getSymTag() == PDB_SymType::Compiland)
2054 return LexParentId;
2055 LexParentId = LexParent->getRawSymbol().getLexicalParentId();
2056 }
2057 }
2058
2059 return 0;
2060}

/usr/include/c++/v1/__memory/shared_ptr.h

1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___MEMORY_SHARED_PTR_H
11#define _LIBCPP___MEMORY_SHARED_PTR_H
12
13#include <__availability>
14#include <__config>
15#include <__functional_base>
16#include <__functional/binary_function.h>
17#include <__functional/operations.h>
18#include <__functional/reference_wrapper.h>
19#include <__memory/addressof.h>
20#include <__memory/allocation_guard.h>
21#include <__memory/allocator_traits.h>
22#include <__memory/allocator.h>
23#include <__memory/compressed_pair.h>
24#include <__memory/pointer_traits.h>
25#include <__memory/unique_ptr.h>
26#include <__utility/forward.h>
27#include <cstddef>
28#include <cstdlib> // abort
29#include <iosfwd>
30#include <stdexcept>
31#include <typeinfo>
32#include <type_traits>
33#include <utility>
34#if !defined(_LIBCPP_HAS_NO_ATOMIC_HEADER)
35# include <atomic>
36#endif
37
38#if _LIBCPP_STD_VER14 <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR)
39# include <__memory/auto_ptr.h>
40#endif
41
42#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
43#pragma GCC system_header
44#endif
45
46_LIBCPP_PUSH_MACROSpush_macro("min") push_macro("max")
47#include <__undef_macros>
48
49_LIBCPP_BEGIN_NAMESPACE_STDnamespace std { inline namespace __1 {
50
51template <class _Alloc>
52class __allocator_destructor
53{
54 typedef _LIBCPP_NODEBUG_TYPE__attribute__((nodebug)) allocator_traits<_Alloc> __alloc_traits;
55public:
56 typedef _LIBCPP_NODEBUG_TYPE__attribute__((nodebug)) typename __alloc_traits::pointer pointer;
57 typedef _LIBCPP_NODEBUG_TYPE__attribute__((nodebug)) typename __alloc_traits::size_type size_type;
58private:
59 _Alloc& __alloc_;
60 size_type __s_;
61public:
62 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
__allocator_destructor(_Alloc& __a, size_type __s)
63 _NOEXCEPTnoexcept
64 : __alloc_(__a), __s_(__s) {}
65 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
66 void operator()(pointer __p) _NOEXCEPTnoexcept
67 {__alloc_traits::deallocate(__alloc_, __p, __s_);}
68};
69
70// NOTE: Relaxed and acq/rel atomics (for increment and decrement respectively)
71// should be sufficient for thread safety.
72// See https://llvm.org/PR22803
73#if defined(__clang__1) && __has_builtin(__atomic_add_fetch)1 \
74 && defined(__ATOMIC_RELAXED0) \
75 && defined(__ATOMIC_ACQ_REL4)
76# define _LIBCPP_HAS_BUILTIN_ATOMIC_SUPPORT
77#elif defined(_LIBCPP_COMPILER_GCC)
78# define _LIBCPP_HAS_BUILTIN_ATOMIC_SUPPORT
79#endif
80
81template <class _ValueType>
82inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
83_ValueType __libcpp_relaxed_load(_ValueType const* __value) {
84#if !defined(_LIBCPP_HAS_NO_THREADS) && \
85 defined(__ATOMIC_RELAXED0) && \
86 (__has_builtin(__atomic_load_n)1 || defined(_LIBCPP_COMPILER_GCC))
87 return __atomic_load_n(__value, __ATOMIC_RELAXED0);
88#else
89 return *__value;
90#endif
91}
92
93template <class _ValueType>
94inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
95_ValueType __libcpp_acquire_load(_ValueType const* __value) {
96#if !defined(_LIBCPP_HAS_NO_THREADS) && \
97 defined(__ATOMIC_ACQUIRE2) && \
98 (__has_builtin(__atomic_load_n)1 || defined(_LIBCPP_COMPILER_GCC))
99 return __atomic_load_n(__value, __ATOMIC_ACQUIRE2);
100#else
101 return *__value;
102#endif
103}
104
105template <class _Tp>
106inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
_Tp
107__libcpp_atomic_refcount_increment(_Tp& __t) _NOEXCEPTnoexcept
108{
109#if defined(_LIBCPP_HAS_BUILTIN_ATOMIC_SUPPORT) && !defined(_LIBCPP_HAS_NO_THREADS)
110 return __atomic_add_fetch(&__t, 1, __ATOMIC_RELAXED0);
111#else
112 return __t += 1;
113#endif
114}
115
116template <class _Tp>
117inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
_Tp
118__libcpp_atomic_refcount_decrement(_Tp& __t) _NOEXCEPTnoexcept
119{
120#if defined(_LIBCPP_HAS_BUILTIN_ATOMIC_SUPPORT) && !defined(_LIBCPP_HAS_NO_THREADS)
121 return __atomic_add_fetch(&__t, -1, __ATOMIC_ACQ_REL4);
122#else
123 return __t -= 1;
124#endif
125}
126
127class _LIBCPP_EXCEPTION_ABI__attribute__ ((__visibility__("default"))) bad_weak_ptr
128 : public std::exception
129{
130public:
131 bad_weak_ptr() _NOEXCEPTnoexcept = default;
132 bad_weak_ptr(const bad_weak_ptr&) _NOEXCEPTnoexcept = default;
133 virtual ~bad_weak_ptr() _NOEXCEPTnoexcept;
134 virtual const char* what() const _NOEXCEPTnoexcept;
135};
136
137_LIBCPP_NORETURN[[noreturn]] inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
138void __throw_bad_weak_ptr()
139{
140#ifndef _LIBCPP_NO_EXCEPTIONS
141 throw bad_weak_ptr();
142#else
143 _VSTDstd::__1::abort();
144#endif
145}
146
147template<class _Tp> class _LIBCPP_TEMPLATE_VIS__attribute__ ((__type_visibility__("default"))) weak_ptr;
148
149class _LIBCPP_TYPE_VIS__attribute__ ((__visibility__("default"))) __shared_count
150{
151 __shared_count(const __shared_count&);
152 __shared_count& operator=(const __shared_count&);
153
154protected:
155 long __shared_owners_;
156 virtual ~__shared_count();
157private:
158 virtual void __on_zero_shared() _NOEXCEPTnoexcept = 0;
159
160public:
161 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
162 explicit __shared_count(long __refs = 0) _NOEXCEPTnoexcept
163 : __shared_owners_(__refs) {}
164
165#if defined(_LIBCPP_BUILDING_LIBRARY) && \
166 defined(_LIBCPP_DEPRECATED_ABI_LEGACY_LIBRARY_DEFINITIONS_FOR_INLINE_FUNCTIONS)
167 void __add_shared() _NOEXCEPTnoexcept;
168 bool __release_shared() _NOEXCEPTnoexcept;
169#else
170 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
171 void __add_shared() _NOEXCEPTnoexcept {
172 __libcpp_atomic_refcount_increment(__shared_owners_);
173 }
174 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
175 bool __release_shared() _NOEXCEPTnoexcept {
176 if (__libcpp_atomic_refcount_decrement(__shared_owners_) == -1) {
177 __on_zero_shared();
178 return true;
179 }
180 return false;
181 }
182#endif
183 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
184 long use_count() const _NOEXCEPTnoexcept {
185 return __libcpp_relaxed_load(&__shared_owners_) + 1;
186 }
187};
188
189class _LIBCPP_TYPE_VIS__attribute__ ((__visibility__("default"))) __shared_weak_count
190 : private __shared_count
191{
192 long __shared_weak_owners_;
193
194public:
195 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
196 explicit __shared_weak_count(long __refs = 0) _NOEXCEPTnoexcept
197 : __shared_count(__refs),
198 __shared_weak_owners_(__refs) {}
199protected:
200 virtual ~__shared_weak_count();
201
202public:
203#if defined(_LIBCPP_BUILDING_LIBRARY) && \
204 defined(_LIBCPP_DEPRECATED_ABI_LEGACY_LIBRARY_DEFINITIONS_FOR_INLINE_FUNCTIONS)
205 void __add_shared() _NOEXCEPTnoexcept;
206 void __add_weak() _NOEXCEPTnoexcept;
207 void __release_shared() _NOEXCEPTnoexcept;
208#else
209 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
210 void __add_shared() _NOEXCEPTnoexcept {
211 __shared_count::__add_shared();
212 }
213 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
214 void __add_weak() _NOEXCEPTnoexcept {
215 __libcpp_atomic_refcount_increment(__shared_weak_owners_);
216 }
217 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
218 void __release_shared() _NOEXCEPTnoexcept {
219 if (__shared_count::__release_shared())
220 __release_weak();
221 }
222#endif
223 void __release_weak() _NOEXCEPTnoexcept;
224 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
225 long use_count() const _NOEXCEPTnoexcept {return __shared_count::use_count();}
226 __shared_weak_count* lock() _NOEXCEPTnoexcept;
227
228 virtual const void* __get_deleter(const type_info&) const _NOEXCEPTnoexcept;
229private:
230 virtual void __on_zero_shared_weak() _NOEXCEPTnoexcept = 0;
231};
232
233template <class _Tp, class _Dp, class _Alloc>
234class __shared_ptr_pointer
235 : public __shared_weak_count
236{
237 __compressed_pair<__compressed_pair<_Tp, _Dp>, _Alloc> __data_;
238public:
239 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
240 __shared_ptr_pointer(_Tp __p, _Dp __d, _Alloc __a)
241 : __data_(__compressed_pair<_Tp, _Dp>(__p, _VSTDstd::__1::move(__d)), _VSTDstd::__1::move(__a)) {}
242
243#ifndef _LIBCPP_NO_RTTI
244 virtual const void* __get_deleter(const type_info&) const _NOEXCEPTnoexcept;
245#endif
246
247private:
248 virtual void __on_zero_shared() _NOEXCEPTnoexcept;
249 virtual void __on_zero_shared_weak() _NOEXCEPTnoexcept;
250};
251
252#ifndef _LIBCPP_NO_RTTI
253
254template <class _Tp, class _Dp, class _Alloc>
255const void*
256__shared_ptr_pointer<_Tp, _Dp, _Alloc>::__get_deleter(const type_info& __t) const _NOEXCEPTnoexcept
257{
258 return __t == typeid(_Dp) ? _VSTDstd::__1::addressof(__data_.first().second()) : nullptr;
259}
260
261#endif // _LIBCPP_NO_RTTI
262
263template <class _Tp, class _Dp, class _Alloc>
264void
265__shared_ptr_pointer<_Tp, _Dp, _Alloc>::__on_zero_shared() _NOEXCEPTnoexcept
266{
267 __data_.first().second()(__data_.first().first());
268 __data_.first().second().~_Dp();
269}
270
271template <class _Tp, class _Dp, class _Alloc>
272void
273__shared_ptr_pointer<_Tp, _Dp, _Alloc>::__on_zero_shared_weak() _NOEXCEPTnoexcept
274{
275 typedef typename __allocator_traits_rebind<_Alloc, __shared_ptr_pointer>::type _Al;
276 typedef allocator_traits<_Al> _ATraits;
277 typedef pointer_traits<typename _ATraits::pointer> _PTraits;
278
279 _Al __a(__data_.second());
280 __data_.second().~_Alloc();
281 __a.deallocate(_PTraits::pointer_to(*this), 1);
282}
283
284template <class _Tp, class _Alloc>
285struct __shared_ptr_emplace
286 : __shared_weak_count
287{
288 template<class ..._Args>
289 _LIBCPP_HIDE_FROM_ABI__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
290 explicit __shared_ptr_emplace(_Alloc __a, _Args&& ...__args)
291 : __storage_(_VSTDstd::__1::move(__a))
292 {
293#if _LIBCPP_STD_VER14 > 17
294 using _TpAlloc = typename __allocator_traits_rebind<_Alloc, _Tp>::type;
295 _TpAlloc __tmp(*__get_alloc());
296 allocator_traits<_TpAlloc>::construct(__tmp, __get_elem(), _VSTDstd::__1::forward<_Args>(__args)...);
297#else
298 ::new ((void*)__get_elem()) _Tp(_VSTDstd::__1::forward<_Args>(__args)...);
299#endif
300 }
301
302 _LIBCPP_HIDE_FROM_ABI__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
303 _Alloc* __get_alloc() _NOEXCEPTnoexcept { return __storage_.__get_alloc(); }
304
305 _LIBCPP_HIDE_FROM_ABI__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
306 _Tp* __get_elem() _NOEXCEPTnoexcept { return __storage_.__get_elem(); }
307
308private:
309 virtual void __on_zero_shared() _NOEXCEPTnoexcept {
310#if _LIBCPP_STD_VER14 > 17
311 using _TpAlloc = typename __allocator_traits_rebind<_Alloc, _Tp>::type;
312 _TpAlloc __tmp(*__get_alloc());
313 allocator_traits<_TpAlloc>::destroy(__tmp, __get_elem());
314#else
315 __get_elem()->~_Tp();
316#endif
317 }
318
319 virtual void __on_zero_shared_weak() _NOEXCEPTnoexcept {
320 using _ControlBlockAlloc = typename __allocator_traits_rebind<_Alloc, __shared_ptr_emplace>::type;
321 using _ControlBlockPointer = typename allocator_traits<_ControlBlockAlloc>::pointer;
322 _ControlBlockAlloc __tmp(*__get_alloc());
323 __storage_.~_Storage();
324 allocator_traits<_ControlBlockAlloc>::deallocate(__tmp,
325 pointer_traits<_ControlBlockPointer>::pointer_to(*this), 1);
326 }
327
328 // This class implements the control block for non-array shared pointers created
329 // through `std::allocate_shared` and `std::make_shared`.
330 //
331 // In previous versions of the library, we used a compressed pair to store
332 // both the _Alloc and the _Tp. This implies using EBO, which is incompatible
333 // with Allocator construction for _Tp. To allow implementing P0674 in C++20,
334 // we now use a properly aligned char buffer while making sure that we maintain
335 // the same layout that we had when we used a compressed pair.
336 using _CompressedPair = __compressed_pair<_Alloc, _Tp>;
337 struct _ALIGNAS_TYPE(_CompressedPair)alignas(_CompressedPair) _Storage {
338 char __blob_[sizeof(_CompressedPair)];
339
340 _LIBCPP_HIDE_FROM_ABI__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
explicit _Storage(_Alloc&& __a) {
341 ::new ((void*)__get_alloc()) _Alloc(_VSTDstd::__1::move(__a));
342 }
343 _LIBCPP_HIDE_FROM_ABI__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
~_Storage() {
344 __get_alloc()->~_Alloc();
345 }
346 _Alloc* __get_alloc() _NOEXCEPTnoexcept {
347 _CompressedPair *__as_pair = reinterpret_cast<_CompressedPair*>(__blob_);
348 typename _CompressedPair::_Base1* __first = _CompressedPair::__get_first_base(__as_pair);
349 _Alloc *__alloc = reinterpret_cast<_Alloc*>(__first);
350 return __alloc;
351 }
352 _LIBCPP_NO_CFI__attribute__((__no_sanitize__("cfi"))) _Tp* __get_elem() _NOEXCEPTnoexcept {
353 _CompressedPair *__as_pair = reinterpret_cast<_CompressedPair*>(__blob_);
354 typename _CompressedPair::_Base2* __second = _CompressedPair::__get_second_base(__as_pair);
355 _Tp *__elem = reinterpret_cast<_Tp*>(__second);
356 return __elem;
357 }
358 };
359
360 static_assert(_LIBCPP_ALIGNOF(_Storage)alignof(_Storage) == _LIBCPP_ALIGNOF(_CompressedPair)alignof(_CompressedPair), "");
361 static_assert(sizeof(_Storage) == sizeof(_CompressedPair), "");
362 _Storage __storage_;
363};
364
365struct __shared_ptr_dummy_rebind_allocator_type;
366template <>
367class _LIBCPP_TEMPLATE_VIS__attribute__ ((__type_visibility__("default"))) allocator<__shared_ptr_dummy_rebind_allocator_type>
368{
369public:
370 template <class _Other>
371 struct rebind
372 {
373 typedef allocator<_Other> other;
374 };
375};
376
377template<class _Tp> class _LIBCPP_TEMPLATE_VIS__attribute__ ((__type_visibility__("default"))) enable_shared_from_this;
378
379template<class _Tp, class _Up>
380struct __compatible_with
381#if _LIBCPP_STD_VER14 > 14
382 : is_convertible<remove_extent_t<_Tp>*, remove_extent_t<_Up>*> {};
383#else
384 : is_convertible<_Tp*, _Up*> {};
385#endif // _LIBCPP_STD_VER > 14
386
387template <class _Ptr, class = void>
388struct __is_deletable : false_type { };
389template <class _Ptr>
390struct __is_deletable<_Ptr, decltype(delete declval<_Ptr>())> : true_type { };
391
392template <class _Ptr, class = void>
393struct __is_array_deletable : false_type { };
394template <class _Ptr>
395struct __is_array_deletable<_Ptr, decltype(delete[] declval<_Ptr>())> : true_type { };
396
397template <class _Dp, class _Pt,
398 class = decltype(declval<_Dp>()(declval<_Pt>()))>
399static true_type __well_formed_deleter_test(int);
400
401template <class, class>
402static false_type __well_formed_deleter_test(...);
403
404template <class _Dp, class _Pt>
405struct __well_formed_deleter : decltype(__well_formed_deleter_test<_Dp, _Pt>(0)) {};
406
407template<class _Dp, class _Tp, class _Yp>
408struct __shared_ptr_deleter_ctor_reqs
409{
410 static const bool value = __compatible_with<_Tp, _Yp>::value &&
411 is_move_constructible<_Dp>::value &&
412 __well_formed_deleter<_Dp, _Tp*>::value;
413};
414
415#if defined(_LIBCPP_ABI_ENABLE_SHARED_PTR_TRIVIAL_ABI)
416# define _LIBCPP_SHARED_PTR_TRIVIAL_ABI __attribute__((trivial_abi))
417#else
418# define _LIBCPP_SHARED_PTR_TRIVIAL_ABI
419#endif
420
421template<class _Tp>
422class _LIBCPP_SHARED_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS__attribute__ ((__type_visibility__("default"))) shared_ptr
423{
424public:
425#if _LIBCPP_STD_VER14 > 14
426 typedef weak_ptr<_Tp> weak_type;
427 typedef remove_extent_t<_Tp> element_type;
428#else
429 typedef _Tp element_type;
430#endif
431
432private:
433 element_type* __ptr_;
434 __shared_weak_count* __cntrl_;
435
436 struct __nat {int __for_bool_;};
437public:
438 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
439 _LIBCPP_CONSTEXPRconstexpr shared_ptr() _NOEXCEPTnoexcept;
440 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
441 _LIBCPP_CONSTEXPRconstexpr shared_ptr(nullptr_t) _NOEXCEPTnoexcept;
442
443 template<class _Yp, class = _EnableIf<
444 _And<
445 __compatible_with<_Yp, _Tp>
446 // In C++03 we get errors when trying to do SFINAE with the
447 // delete operator, so we always pretend that it's deletable.
448 // The same happens on GCC.
449#if !defined(_LIBCPP_CXX03_LANG) && !defined(_LIBCPP_COMPILER_GCC)
450 , _If<is_array<_Tp>::value, __is_array_deletable<_Yp*>, __is_deletable<_Yp*> >
451#endif
452 >::value
453 > >
454 explicit shared_ptr(_Yp* __p) : __ptr_(__p) {
455 unique_ptr<_Yp> __hold(__p);
456 typedef typename __shared_ptr_default_allocator<_Yp>::type _AllocT;
457 typedef __shared_ptr_pointer<_Yp*, __shared_ptr_default_delete<_Tp, _Yp>, _AllocT > _CntrlBlk;
458 __cntrl_ = new _CntrlBlk(__p, __shared_ptr_default_delete<_Tp, _Yp>(), _AllocT());
459 __hold.release();
460 __enable_weak_this(__p, __p);
461 }
462
463 template<class _Yp, class _Dp>
464 shared_ptr(_Yp* __p, _Dp __d,
465 typename enable_if<__shared_ptr_deleter_ctor_reqs<_Dp, _Yp, element_type>::value, __nat>::type = __nat());
466 template<class _Yp, class _Dp, class _Alloc>
467 shared_ptr(_Yp* __p, _Dp __d, _Alloc __a,
468 typename enable_if<__shared_ptr_deleter_ctor_reqs<_Dp, _Yp, element_type>::value, __nat>::type = __nat());
469 template <class _Dp> shared_ptr(nullptr_t __p, _Dp __d);
470 template <class _Dp, class _Alloc> shared_ptr(nullptr_t __p, _Dp __d, _Alloc __a);
471 template<class _Yp> _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
shared_ptr(const shared_ptr<_Yp>& __r, element_type* __p) _NOEXCEPTnoexcept;
472 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
473 shared_ptr(const shared_ptr& __r) _NOEXCEPTnoexcept;
474 template<class _Yp>
475 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
476 shared_ptr(const shared_ptr<_Yp>& __r,
477 typename enable_if<__compatible_with<_Yp, element_type>::value, __nat>::type = __nat())
478 _NOEXCEPTnoexcept;
479 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
480 shared_ptr(shared_ptr&& __r) _NOEXCEPTnoexcept;
481 template<class _Yp> _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
shared_ptr(shared_ptr<_Yp>&& __r,
482 typename enable_if<__compatible_with<_Yp, element_type>::value, __nat>::type = __nat())
483 _NOEXCEPTnoexcept;
484 template<class _Yp> explicit shared_ptr(const weak_ptr<_Yp>& __r,
485 typename enable_if<is_convertible<_Yp*, element_type*>::value, __nat>::type= __nat());
486#if _LIBCPP_STD_VER14 <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR)
487 template<class _Yp>
488 shared_ptr(auto_ptr<_Yp>&& __r,
489 typename enable_if<is_convertible<_Yp*, element_type*>::value, __nat>::type = __nat());
490#endif
491 template <class _Yp, class _Dp>
492 shared_ptr(unique_ptr<_Yp, _Dp>&&,
493 typename enable_if
494 <
495 !is_lvalue_reference<_Dp>::value &&
496 is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value,
497 __nat
498 >::type = __nat());
499 template <class _Yp, class _Dp>
500 shared_ptr(unique_ptr<_Yp, _Dp>&&,
501 typename enable_if
502 <
503 is_lvalue_reference<_Dp>::value &&
504 is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value,
505 __nat
506 >::type = __nat());
507
508 ~shared_ptr();
509
510 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
511 shared_ptr& operator=(const shared_ptr& __r) _NOEXCEPTnoexcept;
512 template<class _Yp>
513 typename enable_if
514 <
515 __compatible_with<_Yp, element_type>::value,
516 shared_ptr&
517 >::type
518 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
519 operator=(const shared_ptr<_Yp>& __r) _NOEXCEPTnoexcept;
520 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
521 shared_ptr& operator=(shared_ptr&& __r) _NOEXCEPTnoexcept;
522 template<class _Yp>
523 typename enable_if
524 <
525 __compatible_with<_Yp, element_type>::value,
526 shared_ptr&
527 >::type
528 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
529 operator=(shared_ptr<_Yp>&& __r);
530#if _LIBCPP_STD_VER14 <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR)
531 template<class _Yp>
532 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
533 typename enable_if
534 <
535 !is_array<_Yp>::value &&
536 is_convertible<_Yp*, element_type*>::value,
537 shared_ptr
538 >::type&
539 operator=(auto_ptr<_Yp>&& __r);
540#endif
541 template <class _Yp, class _Dp>
542 typename enable_if
543 <
544 is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value,
545 shared_ptr&
546 >::type
547 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
548 operator=(unique_ptr<_Yp, _Dp>&& __r);
549
550 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
551 void swap(shared_ptr& __r) _NOEXCEPTnoexcept;
552 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
553 void reset() _NOEXCEPTnoexcept;
554 template<class _Yp>
555 typename enable_if
556 <
557 __compatible_with<_Yp, element_type>::value,
558 void
559 >::type
560 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
561 reset(_Yp* __p);
562 template<class _Yp, class _Dp>
563 typename enable_if
564 <
565 __compatible_with<_Yp, element_type>::value,
566 void
567 >::type
568 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
569 reset(_Yp* __p, _Dp __d);
570 template<class _Yp, class _Dp, class _Alloc>
571 typename enable_if
572 <
573 __compatible_with<_Yp, element_type>::value,
574 void
575 >::type
576 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
577 reset(_Yp* __p, _Dp __d, _Alloc __a);
578
579 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
580 element_type* get() const _NOEXCEPTnoexcept {return __ptr_;}
581 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
582 typename add_lvalue_reference<element_type>::type operator*() const _NOEXCEPTnoexcept
583 {return *__ptr_;}
584 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
585 element_type* operator->() const _NOEXCEPTnoexcept
586 {
587 static_assert(!is_array<_Tp>::value,
588 "std::shared_ptr<T>::operator-> is only valid when T is not an array type.");
589 return __ptr_;
590 }
591 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
592 long use_count() const _NOEXCEPTnoexcept {return __cntrl_ ? __cntrl_->use_count() : 0;}
593 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
594 bool unique() const _NOEXCEPTnoexcept {return use_count() == 1;}
595 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
596 explicit operator bool() const _NOEXCEPTnoexcept {return get() != nullptr;}
6
Assuming the condition is true
7
Returning the value 1, which participates in a condition later
597 template <class _Up>
598 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
599 bool owner_before(shared_ptr<_Up> const& __p) const _NOEXCEPTnoexcept
600 {return __cntrl_ < __p.__cntrl_;}
601 template <class _Up>
602 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
603 bool owner_before(weak_ptr<_Up> const& __p) const _NOEXCEPTnoexcept
604 {return __cntrl_ < __p.__cntrl_;}
605 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
606 bool
607 __owner_equivalent(const shared_ptr& __p) const
608 {return __cntrl_ == __p.__cntrl_;}
609
610#if _LIBCPP_STD_VER14 > 14
611 typename add_lvalue_reference<element_type>::type
612 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
613 operator[](ptrdiff_t __i) const
614 {
615 static_assert(is_array<_Tp>::value,
616 "std::shared_ptr<T>::operator[] is only valid when T is an array type.");
617 return __ptr_[__i];
618 }
619#endif
620
621#ifndef _LIBCPP_NO_RTTI
622 template <class _Dp>
623 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
624 _Dp* __get_deleter() const _NOEXCEPTnoexcept
625 {return static_cast<_Dp*>(__cntrl_
626 ? const_cast<void *>(__cntrl_->__get_deleter(typeid(_Dp)))
627 : nullptr);}
628#endif // _LIBCPP_NO_RTTI
629
630 template<class _Yp, class _CntrlBlk>
631 static shared_ptr<_Tp>
632 __create_with_control_block(_Yp* __p, _CntrlBlk* __cntrl) _NOEXCEPTnoexcept
633 {
634 shared_ptr<_Tp> __r;
635 __r.__ptr_ = __p;
636 __r.__cntrl_ = __cntrl;
637 __r.__enable_weak_this(__r.__ptr_, __r.__ptr_);
638 return __r;
639 }
640
641private:
642 template <class _Yp, bool = is_function<_Yp>::value>
643 struct __shared_ptr_default_allocator
644 {
645 typedef allocator<_Yp> type;
646 };
647
648 template <class _Yp>
649 struct __shared_ptr_default_allocator<_Yp, true>
650 {
651 typedef allocator<__shared_ptr_dummy_rebind_allocator_type> type;
652 };
653
654 template <class _Yp, class _OrigPtr>
655 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
656 typename enable_if<is_convertible<_OrigPtr*,
657 const enable_shared_from_this<_Yp>*
658 >::value,
659 void>::type
660 __enable_weak_this(const enable_shared_from_this<_Yp>* __e,
661 _OrigPtr* __ptr) _NOEXCEPTnoexcept
662 {
663 typedef typename remove_cv<_Yp>::type _RawYp;
664 if (__e && __e->__weak_this_.expired())
665 {
666 __e->__weak_this_ = shared_ptr<_RawYp>(*this,
667 const_cast<_RawYp*>(static_cast<const _Yp*>(__ptr)));
668 }
669 }
670
671 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
void __enable_weak_this(...) _NOEXCEPTnoexcept {}
672
673 template <class, class _Yp>
674 struct __shared_ptr_default_delete
675 : default_delete<_Yp> {};
676
677 template <class _Yp, class _Un, size_t _Sz>
678 struct __shared_ptr_default_delete<_Yp[_Sz], _Un>
679 : default_delete<_Yp[]> {};
680
681 template <class _Yp, class _Un>
682 struct __shared_ptr_default_delete<_Yp[], _Un>
683 : default_delete<_Yp[]> {};
684
685 template <class _Up> friend class _LIBCPP_TEMPLATE_VIS__attribute__ ((__type_visibility__("default"))) shared_ptr;
686 template <class _Up> friend class _LIBCPP_TEMPLATE_VIS__attribute__ ((__type_visibility__("default"))) weak_ptr;
687};
688
689#ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES
690template<class _Tp>
691shared_ptr(weak_ptr<_Tp>) -> shared_ptr<_Tp>;
692template<class _Tp, class _Dp>
693shared_ptr(unique_ptr<_Tp, _Dp>) -> shared_ptr<_Tp>;
694#endif
695
696template<class _Tp>
697inline
698_LIBCPP_CONSTEXPRconstexpr
699shared_ptr<_Tp>::shared_ptr() _NOEXCEPTnoexcept
700 : __ptr_(nullptr),
701 __cntrl_(nullptr)
702{
703}
704
705template<class _Tp>
706inline
707_LIBCPP_CONSTEXPRconstexpr
708shared_ptr<_Tp>::shared_ptr(nullptr_t) _NOEXCEPTnoexcept
709 : __ptr_(nullptr),
710 __cntrl_(nullptr)
711{
712}
713
714template<class _Tp>
715template<class _Yp, class _Dp>
716shared_ptr<_Tp>::shared_ptr(_Yp* __p, _Dp __d,
717 typename enable_if<__shared_ptr_deleter_ctor_reqs<_Dp, _Yp, element_type>::value, __nat>::type)
718 : __ptr_(__p)
719{
720#ifndef _LIBCPP_NO_EXCEPTIONS
721 try
722 {
723#endif // _LIBCPP_NO_EXCEPTIONS
724 typedef typename __shared_ptr_default_allocator<_Yp>::type _AllocT;
725 typedef __shared_ptr_pointer<_Yp*, _Dp, _AllocT > _CntrlBlk;
726#ifndef _LIBCPP_CXX03_LANG
727 __cntrl_ = new _CntrlBlk(__p, _VSTDstd::__1::move(__d), _AllocT());
728#else
729 __cntrl_ = new _CntrlBlk(__p, __d, _AllocT());
730#endif // not _LIBCPP_CXX03_LANG
731 __enable_weak_this(__p, __p);
732#ifndef _LIBCPP_NO_EXCEPTIONS
733 }
734 catch (...)
735 {
736 __d(__p);
737 throw;
738 }
739#endif // _LIBCPP_NO_EXCEPTIONS
740}
741
742template<class _Tp>
743template<class _Dp>
744shared_ptr<_Tp>::shared_ptr(nullptr_t __p, _Dp __d)
745 : __ptr_(nullptr)
746{
747#ifndef _LIBCPP_NO_EXCEPTIONS
748 try
749 {
750#endif // _LIBCPP_NO_EXCEPTIONS
751 typedef typename __shared_ptr_default_allocator<_Tp>::type _AllocT;
752 typedef __shared_ptr_pointer<nullptr_t, _Dp, _AllocT > _CntrlBlk;
753#ifndef _LIBCPP_CXX03_LANG
754 __cntrl_ = new _CntrlBlk(__p, _VSTDstd::__1::move(__d), _AllocT());
755#else
756 __cntrl_ = new _CntrlBlk(__p, __d, _AllocT());
757#endif // not _LIBCPP_CXX03_LANG
758#ifndef _LIBCPP_NO_EXCEPTIONS
759 }
760 catch (...)
761 {
762 __d(__p);
763 throw;
764 }
765#endif // _LIBCPP_NO_EXCEPTIONS
766}
767
768template<class _Tp>
769template<class _Yp, class _Dp, class _Alloc>
770shared_ptr<_Tp>::shared_ptr(_Yp* __p, _Dp __d, _Alloc __a,
771 typename enable_if<__shared_ptr_deleter_ctor_reqs<_Dp, _Yp, element_type>::value, __nat>::type)
772 : __ptr_(__p)
773{
774#ifndef _LIBCPP_NO_EXCEPTIONS
775 try
776 {
777#endif // _LIBCPP_NO_EXCEPTIONS
778 typedef __shared_ptr_pointer<_Yp*, _Dp, _Alloc> _CntrlBlk;
779 typedef typename __allocator_traits_rebind<_Alloc, _CntrlBlk>::type _A2;
780 typedef __allocator_destructor<_A2> _D2;
781 _A2 __a2(__a);
782 unique_ptr<_CntrlBlk, _D2> __hold2(__a2.allocate(1), _D2(__a2, 1));
783 ::new ((void*)_VSTDstd::__1::addressof(*__hold2.get()))
784#ifndef _LIBCPP_CXX03_LANG
785 _CntrlBlk(__p, _VSTDstd::__1::move(__d), __a);
786#else
787 _CntrlBlk(__p, __d, __a);
788#endif // not _LIBCPP_CXX03_LANG
789 __cntrl_ = _VSTDstd::__1::addressof(*__hold2.release());
790 __enable_weak_this(__p, __p);
791#ifndef _LIBCPP_NO_EXCEPTIONS
792 }
793 catch (...)
794 {
795 __d(__p);
796 throw;
797 }
798#endif // _LIBCPP_NO_EXCEPTIONS
799}
800
801template<class _Tp>
802template<class _Dp, class _Alloc>
803shared_ptr<_Tp>::shared_ptr(nullptr_t __p, _Dp __d, _Alloc __a)
804 : __ptr_(nullptr)
805{
806#ifndef _LIBCPP_NO_EXCEPTIONS
807 try
808 {
809#endif // _LIBCPP_NO_EXCEPTIONS
810 typedef __shared_ptr_pointer<nullptr_t, _Dp, _Alloc> _CntrlBlk;
811 typedef typename __allocator_traits_rebind<_Alloc, _CntrlBlk>::type _A2;
812 typedef __allocator_destructor<_A2> _D2;
813 _A2 __a2(__a);
814 unique_ptr<_CntrlBlk, _D2> __hold2(__a2.allocate(1), _D2(__a2, 1));
815 ::new ((void*)_VSTDstd::__1::addressof(*__hold2.get()))
816#ifndef _LIBCPP_CXX03_LANG
817 _CntrlBlk(__p, _VSTDstd::__1::move(__d), __a);
818#else
819 _CntrlBlk(__p, __d, __a);
820#endif // not _LIBCPP_CXX03_LANG
821 __cntrl_ = _VSTDstd::__1::addressof(*__hold2.release());
822#ifndef _LIBCPP_NO_EXCEPTIONS
823 }
824 catch (...)
825 {
826 __d(__p);
827 throw;
828 }
829#endif // _LIBCPP_NO_EXCEPTIONS
830}
831
832template<class _Tp>
833template<class _Yp>
834inline
835shared_ptr<_Tp>::shared_ptr(const shared_ptr<_Yp>& __r, element_type *__p) _NOEXCEPTnoexcept
836 : __ptr_(__p),
837 __cntrl_(__r.__cntrl_)
838{
839 if (__cntrl_)
840 __cntrl_->__add_shared();
841}
842
843template<class _Tp>
844inline
845shared_ptr<_Tp>::shared_ptr(const shared_ptr& __r) _NOEXCEPTnoexcept
846 : __ptr_(__r.__ptr_),
847 __cntrl_(__r.__cntrl_)
848{
849 if (__cntrl_)
850 __cntrl_->__add_shared();
851}
852
853template<class _Tp>
854template<class _Yp>
855inline
856shared_ptr<_Tp>::shared_ptr(const shared_ptr<_Yp>& __r,
857 typename enable_if<__compatible_with<_Yp, element_type>::value, __nat>::type)
858 _NOEXCEPTnoexcept
859 : __ptr_(__r.__ptr_),
860 __cntrl_(__r.__cntrl_)
861{
862 if (__cntrl_)
863 __cntrl_->__add_shared();
864}
865
866template<class _Tp>
867inline
868shared_ptr<_Tp>::shared_ptr(shared_ptr&& __r) _NOEXCEPTnoexcept
869 : __ptr_(__r.__ptr_),
870 __cntrl_(__r.__cntrl_)
871{
872 __r.__ptr_ = nullptr;
873 __r.__cntrl_ = nullptr;
874}
875
876template<class _Tp>
877template<class _Yp>
878inline
879shared_ptr<_Tp>::shared_ptr(shared_ptr<_Yp>&& __r,
880 typename enable_if<__compatible_with<_Yp, element_type>::value, __nat>::type)
881 _NOEXCEPTnoexcept
882 : __ptr_(__r.__ptr_),
883 __cntrl_(__r.__cntrl_)
884{
885 __r.__ptr_ = nullptr;
886 __r.__cntrl_ = nullptr;
887}
888
889#if _LIBCPP_STD_VER14 <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR)
890template<class _Tp>
891template<class _Yp>
892shared_ptr<_Tp>::shared_ptr(auto_ptr<_Yp>&& __r,
893 typename enable_if<is_convertible<_Yp*, element_type*>::value, __nat>::type)
894 : __ptr_(__r.get())
895{
896 typedef __shared_ptr_pointer<_Yp*, default_delete<_Yp>, allocator<_Yp> > _CntrlBlk;
897 __cntrl_ = new _CntrlBlk(__r.get(), default_delete<_Yp>(), allocator<_Yp>());
898 __enable_weak_this(__r.get(), __r.get());
899 __r.release();
900}
901#endif
902
903template<class _Tp>
904template <class _Yp, class _Dp>
905shared_ptr<_Tp>::shared_ptr(unique_ptr<_Yp, _Dp>&& __r,
906 typename enable_if
907 <
908 !is_lvalue_reference<_Dp>::value &&
909 is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value,
910 __nat
911 >::type)
912 : __ptr_(__r.get())
913{
914#if _LIBCPP_STD_VER14 > 11
915 if (__ptr_ == nullptr)
916 __cntrl_ = nullptr;
917 else
918#endif
919 {
920 typedef typename __shared_ptr_default_allocator<_Yp>::type _AllocT;
921 typedef __shared_ptr_pointer<typename unique_ptr<_Yp, _Dp>::pointer, _Dp, _AllocT > _CntrlBlk;
922 __cntrl_ = new _CntrlBlk(__r.get(), __r.get_deleter(), _AllocT());
923 __enable_weak_this(__r.get(), __r.get());
924 }
925 __r.release();
926}
927
928template<class _Tp>
929template <class _Yp, class _Dp>
930shared_ptr<_Tp>::shared_ptr(unique_ptr<_Yp, _Dp>&& __r,
931 typename enable_if
932 <
933 is_lvalue_reference<_Dp>::value &&
934 is_convertible<typename unique_ptr<_Yp, _Dp>::pointer, element_type*>::value,
935 __nat
936 >::type)
937 : __ptr_(__r.get())
938{
939#if _LIBCPP_STD_VER14 > 11
940 if (__ptr_ == nullptr)
941 __cntrl_ = nullptr;
942 else
943#endif
944 {
945 typedef typename __shared_ptr_default_allocator<_Yp>::type _AllocT;
946 typedef __shared_ptr_pointer<typename unique_ptr<_Yp, _Dp>::pointer,
947 reference_wrapper<typename remove_reference<_Dp>::type>,
948 _AllocT > _CntrlBlk;
949 __cntrl_ = new _CntrlBlk(__r.get(), _VSTDstd::__1::ref(__r.get_deleter()), _AllocT());
950 __enable_weak_this(__r.get(), __r.get());
951 }
952 __r.release();
953}
954
955template<class _Tp>
956shared_ptr<_Tp>::~shared_ptr()
957{
958 if (__cntrl_)
959 __cntrl_->__release_shared();
960}
961
962template<class _Tp>
963inline
964shared_ptr<_Tp>&
965shared_ptr<_Tp>::operator=(const shared_ptr& __r) _NOEXCEPTnoexcept
966{
967 shared_ptr(__r).swap(*this);
968 return *this;
969}
970
971template<class _Tp>
972template<class _Yp>
973inline
974typename enable_if
975<
976 __compatible_with<_Yp, typename shared_ptr<_Tp>::element_type>::value,
977 shared_ptr<_Tp>&
978>::type
979shared_ptr<_Tp>::operator=(const shared_ptr<_Yp>& __r) _NOEXCEPTnoexcept
980{
981 shared_ptr(__r).swap(*this);
982 return *this;
983}
984
985template<class _Tp>
986inline
987shared_ptr<_Tp>&
988shared_ptr<_Tp>::operator=(shared_ptr&& __r) _NOEXCEPTnoexcept
989{
990 shared_ptr(_VSTDstd::__1::move(__r)).swap(*this);
991 return *this;
992}
993
994template<class _Tp>
995template<class _Yp>
996inline
997typename enable_if
998<
999 __compatible_with<_Yp, typename shared_ptr<_Tp>::element_type>::value,
1000 shared_ptr<_Tp>&
1001>::type
1002shared_ptr<_Tp>::operator=(shared_ptr<_Yp>&& __r)
1003{
1004 shared_ptr(_VSTDstd::__1::move(__r)).swap(*this);
1005 return *this;
1006}
1007
1008#if _LIBCPP_STD_VER14 <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR)
1009template<class _Tp>
1010template<class _Yp>
1011inline
1012typename enable_if
1013<
1014 !is_array<_Yp>::value &&
1015 is_convertible<_Yp*, typename shared_ptr<_Tp>::element_type*>::value,
1016 shared_ptr<_Tp>
1017>::type&
1018shared_ptr<_Tp>::operator=(auto_ptr<_Yp>&& __r)
1019{
1020 shared_ptr(_VSTDstd::__1::move(__r)).swap(*this);
1021 return *this;
1022}
1023#endif
1024
1025template<class _Tp>
1026template <class _Yp, class _Dp>
1027inline
1028typename enable_if
1029<
1030 is_convertible<typename unique_ptr<_Yp, _Dp>::pointer,
1031 typename shared_ptr<_Tp>::element_type*>::value,
1032 shared_ptr<_Tp>&
1033>::type
1034shared_ptr<_Tp>::operator=(unique_ptr<_Yp, _Dp>&& __r)
1035{
1036 shared_ptr(_VSTDstd::__1::move(__r)).swap(*this);
1037 return *this;
1038}
1039
1040template<class _Tp>
1041inline
1042void
1043shared_ptr<_Tp>::swap(shared_ptr& __r) _NOEXCEPTnoexcept
1044{
1045 _VSTDstd::__1::swap(__ptr_, __r.__ptr_);
1046 _VSTDstd::__1::swap(__cntrl_, __r.__cntrl_);
1047}
1048
1049template<class _Tp>
1050inline
1051void
1052shared_ptr<_Tp>::reset() _NOEXCEPTnoexcept
1053{
1054 shared_ptr().swap(*this);
1055}
1056
1057template<class _Tp>
1058template<class _Yp>
1059inline
1060typename enable_if
1061<
1062 __compatible_with<_Yp, typename shared_ptr<_Tp>::element_type>::value,
1063 void
1064>::type
1065shared_ptr<_Tp>::reset(_Yp* __p)
1066{
1067 shared_ptr(__p).swap(*this);
1068}
1069
1070template<class _Tp>
1071template<class _Yp, class _Dp>
1072inline
1073typename enable_if
1074<
1075 __compatible_with<_Yp, typename shared_ptr<_Tp>::element_type>::value,
1076 void
1077>::type
1078shared_ptr<_Tp>::reset(_Yp* __p, _Dp __d)
1079{
1080 shared_ptr(__p, __d).swap(*this);
1081}
1082
1083template<class _Tp>
1084template<class _Yp, class _Dp, class _Alloc>
1085inline
1086typename enable_if
1087<
1088 __compatible_with<_Yp, typename shared_ptr<_Tp>::element_type>::value,
1089 void
1090>::type
1091shared_ptr<_Tp>::reset(_Yp* __p, _Dp __d, _Alloc __a)
1092{
1093 shared_ptr(__p, __d, __a).swap(*this);
1094}
1095
1096//
1097// std::allocate_shared and std::make_shared
1098//
1099template<class _Tp, class _Alloc, class ..._Args, class = _EnableIf<!is_array<_Tp>::value> >
1100_LIBCPP_HIDE_FROM_ABI__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
1101shared_ptr<_Tp> allocate_shared(const _Alloc& __a, _Args&& ...__args)
1102{
1103 using _ControlBlock = __shared_ptr_emplace<_Tp, _Alloc>;
1104 using _ControlBlockAllocator = typename __allocator_traits_rebind<_Alloc, _ControlBlock>::type;
1105 __allocation_guard<_ControlBlockAllocator> __guard(__a, 1);
1106 ::new ((void*)_VSTDstd::__1::addressof(*__guard.__get())) _ControlBlock(__a, _VSTDstd::__1::forward<_Args>(__args)...);
1107 auto __control_block = __guard.__release_ptr();
1108 return shared_ptr<_Tp>::__create_with_control_block((*__control_block).__get_elem(), _VSTDstd::__1::addressof(*__control_block));
1109}
1110
1111template<class _Tp, class ..._Args, class = _EnableIf<!is_array<_Tp>::value> >
1112_LIBCPP_HIDE_FROM_ABI__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
1113shared_ptr<_Tp> make_shared(_Args&& ...__args)
1114{
1115 return _VSTDstd::__1::allocate_shared<_Tp>(allocator<_Tp>(), _VSTDstd::__1::forward<_Args>(__args)...);
1116}
1117
1118template<class _Tp, class _Up>
1119inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
1120bool
1121operator==(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPTnoexcept
1122{
1123 return __x.get() == __y.get();
1124}
1125
1126template<class _Tp, class _Up>
1127inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
1128bool
1129operator!=(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPTnoexcept
1130{
1131 return !(__x == __y);
1132}
1133
1134template<class _Tp, class _Up>
1135inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
1136bool
1137operator<(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPTnoexcept
1138{
1139#if _LIBCPP_STD_VER14 <= 11
1140 typedef typename common_type<_Tp*, _Up*>::type _Vp;
1141 return less<_Vp>()(__x.get(), __y.get());
1142#else
1143 return less<>()(__x.get(), __y.get());
1144#endif
1145
1146}
1147
1148template<class _Tp, class _Up>
1149inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
1150bool
1151operator>(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPTnoexcept
1152{
1153 return __y < __x;
1154}
1155
1156template<class _Tp, class _Up>
1157inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
1158bool
1159operator<=(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPTnoexcept
1160{
1161 return !(__y < __x);
1162}
1163
1164template<class _Tp, class _Up>
1165inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
1166bool
1167operator>=(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPTnoexcept
1168{
1169 return !(__x < __y);
1170}
1171
1172template<class _Tp>
1173inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
1174bool
1175operator==(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPTnoexcept
1176{
1177 return !__x;
1178}
1179
1180template<class _Tp>
1181inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
1182bool
1183operator==(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPTnoexcept
1184{
1185 return !__x;
1186}
1187
1188template<class _Tp>
1189inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
1190bool
1191operator!=(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPTnoexcept
1192{
1193 return static_cast<bool>(__x);
1194}
1195
1196template<class _Tp>
1197inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
1198bool
1199operator!=(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPTnoexcept
1200{
1201 return static_cast<bool>(__x);
1202}
1203
1204template<class _Tp>
1205inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
1206bool
1207operator<(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPTnoexcept
1208{
1209 return less<_Tp*>()(__x.get(), nullptr);
1210}
1211
1212template<class _Tp>
1213inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
1214bool
1215operator<(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPTnoexcept
1216{
1217 return less<_Tp*>()(nullptr, __x.get());
1218}
1219
1220template<class _Tp>
1221inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
1222bool
1223operator>(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPTnoexcept
1224{
1225 return nullptr < __x;
1226}
1227
1228template<class _Tp>
1229inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
1230bool
1231operator>(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPTnoexcept
1232{
1233 return __x < nullptr;
1234}
1235
1236template<class _Tp>
1237inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
1238bool
1239operator<=(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPTnoexcept
1240{
1241 return !(nullptr < __x);
1242}
1243
1244template<class _Tp>
1245inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
1246bool
1247operator<=(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPTnoexcept
1248{
1249 return !(__x < nullptr);
1250}
1251
1252template<class _Tp>
1253inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
1254bool
1255operator>=(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPTnoexcept
1256{
1257 return !(__x < nullptr);
1258}
1259
1260template<class _Tp>
1261inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
1262bool
1263operator>=(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPTnoexcept
1264{
1265 return !(nullptr < __x);
1266}
1267
1268template<class _Tp>
1269inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
1270void
1271swap(shared_ptr<_Tp>& __x, shared_ptr<_Tp>& __y) _NOEXCEPTnoexcept
1272{
1273 __x.swap(__y);
1274}
1275
1276template<class _Tp, class _Up>
1277inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
1278shared_ptr<_Tp>
1279static_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPTnoexcept
1280{
1281 return shared_ptr<_Tp>(__r,
1282 static_cast<
1283 typename shared_ptr<_Tp>::element_type*>(__r.get()));
1284}
1285
1286template<class _Tp, class _Up>
1287inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
1288shared_ptr<_Tp>
1289dynamic_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPTnoexcept
1290{
1291 typedef typename shared_ptr<_Tp>::element_type _ET;
1292 _ET* __p = dynamic_cast<_ET*>(__r.get());
1293 return __p ? shared_ptr<_Tp>(__r, __p) : shared_ptr<_Tp>();
1294}
1295
1296template<class _Tp, class _Up>
1297shared_ptr<_Tp>
1298const_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPTnoexcept
1299{
1300 typedef typename shared_ptr<_Tp>::element_type _RTp;
1301 return shared_ptr<_Tp>(__r, const_cast<_RTp*>(__r.get()));
1302}
1303
1304template<class _Tp, class _Up>
1305shared_ptr<_Tp>
1306reinterpret_pointer_cast(const shared_ptr<_Up>& __r) _NOEXCEPTnoexcept
1307{
1308 return shared_ptr<_Tp>(__r,
1309 reinterpret_cast<
1310 typename shared_ptr<_Tp>::element_type*>(__r.get()));
1311}
1312
1313#ifndef _LIBCPP_NO_RTTI
1314
1315template<class _Dp, class _Tp>
1316inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
1317_Dp*
1318get_deleter(const shared_ptr<_Tp>& __p) _NOEXCEPTnoexcept
1319{
1320 return __p.template __get_deleter<_Dp>();
1321}
1322
1323#endif // _LIBCPP_NO_RTTI
1324
1325template<class _Tp>
1326class _LIBCPP_SHARED_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS__attribute__ ((__type_visibility__("default"))) weak_ptr
1327{
1328public:
1329 typedef _Tp element_type;
1330private:
1331 element_type* __ptr_;
1332 __shared_weak_count* __cntrl_;
1333
1334public:
1335 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
1336 _LIBCPP_CONSTEXPRconstexpr weak_ptr() _NOEXCEPTnoexcept;
1337 template<class _Yp> _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
weak_ptr(shared_ptr<_Yp> const& __r,
1338 typename enable_if<is_convertible<_Yp*, _Tp*>::value, __nat*>::type = 0)
1339 _NOEXCEPTnoexcept;
1340 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
1341 weak_ptr(weak_ptr const& __r) _NOEXCEPTnoexcept;
1342 template<class _Yp> _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
weak_ptr(weak_ptr<_Yp> const& __r,
1343 typename enable_if<is_convertible<_Yp*, _Tp*>::value, __nat*>::type = 0)
1344 _NOEXCEPTnoexcept;
1345
1346 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
1347 weak_ptr(weak_ptr&& __r) _NOEXCEPTnoexcept;
1348 template<class _Yp> _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
weak_ptr(weak_ptr<_Yp>&& __r,
1349 typename enable_if<is_convertible<_Yp*, _Tp*>::value, __nat*>::type = 0)
1350 _NOEXCEPTnoexcept;
1351 ~weak_ptr();
1352
1353 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
1354 weak_ptr& operator=(weak_ptr const& __r) _NOEXCEPTnoexcept;
1355 template<class _Yp>
1356 typename enable_if
1357 <
1358 is_convertible<_Yp*, element_type*>::value,
1359 weak_ptr&
1360 >::type
1361 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
1362 operator=(weak_ptr<_Yp> const& __r) _NOEXCEPTnoexcept;
1363
1364 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
1365 weak_ptr& operator=(weak_ptr&& __r) _NOEXCEPTnoexcept;
1366 template<class _Yp>
1367 typename enable_if
1368 <
1369 is_convertible<_Yp*, element_type*>::value,
1370 weak_ptr&
1371 >::type
1372 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
1373 operator=(weak_ptr<_Yp>&& __r) _NOEXCEPTnoexcept;
1374
1375 template<class _Yp>
1376 typename enable_if
1377 <
1378 is_convertible<_Yp*, element_type*>::value,
1379 weak_ptr&
1380 >::type
1381 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
1382 operator=(shared_ptr<_Yp> const& __r) _NOEXCEPTnoexcept;
1383
1384 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
1385 void swap(weak_ptr& __r) _NOEXCEPTnoexcept;
1386 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
1387 void reset() _NOEXCEPTnoexcept;
1388
1389 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
1390 long use_count() const _NOEXCEPTnoexcept
1391 {return __cntrl_ ? __cntrl_->use_count() : 0;}
1392 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
1393 bool expired() const _NOEXCEPTnoexcept
1394 {return __cntrl_ == nullptr || __cntrl_->use_count() == 0;}
1395 shared_ptr<_Tp> lock() const _NOEXCEPTnoexcept;
1396 template<class _Up>
1397 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
1398 bool owner_before(const shared_ptr<_Up>& __r) const _NOEXCEPTnoexcept
1399 {return __cntrl_ < __r.__cntrl_;}
1400 template<class _Up>
1401 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
1402 bool owner_before(const weak_ptr<_Up>& __r) const _NOEXCEPTnoexcept
1403 {return __cntrl_ < __r.__cntrl_;}
1404
1405 template <class _Up> friend class _LIBCPP_TEMPLATE_VIS__attribute__ ((__type_visibility__("default"))) weak_ptr;
1406 template <class _Up> friend class _LIBCPP_TEMPLATE_VIS__attribute__ ((__type_visibility__("default"))) shared_ptr;
1407};
1408
1409#ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES
1410template<class _Tp>
1411weak_ptr(shared_ptr<_Tp>) -> weak_ptr<_Tp>;
1412#endif
1413
1414template<class _Tp>
1415inline
1416_LIBCPP_CONSTEXPRconstexpr
1417weak_ptr<_Tp>::weak_ptr() _NOEXCEPTnoexcept
1418 : __ptr_(nullptr),
1419 __cntrl_(nullptr)
1420{
1421}
1422
1423template<class _Tp>
1424inline
1425weak_ptr<_Tp>::weak_ptr(weak_ptr const& __r) _NOEXCEPTnoexcept
1426 : __ptr_(__r.__ptr_),
1427 __cntrl_(__r.__cntrl_)
1428{
1429 if (__cntrl_)
1430 __cntrl_->__add_weak();
1431}
1432
1433template<class _Tp>
1434template<class _Yp>
1435inline
1436weak_ptr<_Tp>::weak_ptr(shared_ptr<_Yp> const& __r,
1437 typename enable_if<is_convertible<_Yp*, _Tp*>::value, __nat*>::type)
1438 _NOEXCEPTnoexcept
1439 : __ptr_(__r.__ptr_),
1440 __cntrl_(__r.__cntrl_)
1441{
1442 if (__cntrl_)
1443 __cntrl_->__add_weak();
1444}
1445
1446template<class _Tp>
1447template<class _Yp>
1448inline
1449weak_ptr<_Tp>::weak_ptr(weak_ptr<_Yp> const& __r,
1450 typename enable_if<is_convertible<_Yp*, _Tp*>::value, __nat*>::type)
1451 _NOEXCEPTnoexcept
1452 : __ptr_(__r.__ptr_),
1453 __cntrl_(__r.__cntrl_)
1454{
1455 if (__cntrl_)
1456 __cntrl_->__add_weak();
1457}
1458
1459template<class _Tp>
1460inline
1461weak_ptr<_Tp>::weak_ptr(weak_ptr&& __r) _NOEXCEPTnoexcept
1462 : __ptr_(__r.__ptr_),
1463 __cntrl_(__r.__cntrl_)
1464{
1465 __r.__ptr_ = nullptr;
1466 __r.__cntrl_ = nullptr;
1467}
1468
1469template<class _Tp>
1470template<class _Yp>
1471inline
1472weak_ptr<_Tp>::weak_ptr(weak_ptr<_Yp>&& __r,
1473 typename enable_if<is_convertible<_Yp*, _Tp*>::value, __nat*>::type)
1474 _NOEXCEPTnoexcept
1475 : __ptr_(__r.__ptr_),
1476 __cntrl_(__r.__cntrl_)
1477{
1478 __r.__ptr_ = nullptr;
1479 __r.__cntrl_ = nullptr;
1480}
1481
1482template<class _Tp>
1483weak_ptr<_Tp>::~weak_ptr()
1484{
1485 if (__cntrl_)
1486 __cntrl_->__release_weak();
1487}
1488
1489template<class _Tp>
1490inline
1491weak_ptr<_Tp>&
1492weak_ptr<_Tp>::operator=(weak_ptr const& __r) _NOEXCEPTnoexcept
1493{
1494 weak_ptr(__r).swap(*this);
1495 return *this;
1496}
1497
1498template<class _Tp>
1499template<class _Yp>
1500inline
1501typename enable_if
1502<
1503 is_convertible<_Yp*, _Tp*>::value,
1504 weak_ptr<_Tp>&
1505>::type
1506weak_ptr<_Tp>::operator=(weak_ptr<_Yp> const& __r) _NOEXCEPTnoexcept
1507{
1508 weak_ptr(__r).swap(*this);
1509 return *this;
1510}
1511
1512template<class _Tp>
1513inline
1514weak_ptr<_Tp>&
1515weak_ptr<_Tp>::operator=(weak_ptr&& __r) _NOEXCEPTnoexcept
1516{
1517 weak_ptr(_VSTDstd::__1::move(__r)).swap(*this);
1518 return *this;
1519}
1520
1521template<class _Tp>
1522template<class _Yp>
1523inline
1524typename enable_if
1525<
1526 is_convertible<_Yp*, _Tp*>::value,
1527 weak_ptr<_Tp>&
1528>::type
1529weak_ptr<_Tp>::operator=(weak_ptr<_Yp>&& __r) _NOEXCEPTnoexcept
1530{
1531 weak_ptr(_VSTDstd::__1::move(__r)).swap(*this);
1532 return *this;
1533}
1534
1535template<class _Tp>
1536template<class _Yp>
1537inline
1538typename enable_if
1539<
1540 is_convertible<_Yp*, _Tp*>::value,
1541 weak_ptr<_Tp>&
1542>::type
1543weak_ptr<_Tp>::operator=(shared_ptr<_Yp> const& __r) _NOEXCEPTnoexcept
1544{
1545 weak_ptr(__r).swap(*this);
1546 return *this;
1547}
1548
1549template<class _Tp>
1550inline
1551void
1552weak_ptr<_Tp>::swap(weak_ptr& __r) _NOEXCEPTnoexcept
1553{
1554 _VSTDstd::__1::swap(__ptr_, __r.__ptr_);
1555 _VSTDstd::__1::swap(__cntrl_, __r.__cntrl_);
1556}
1557
1558template<class _Tp>
1559inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
1560void
1561swap(weak_ptr<_Tp>& __x, weak_ptr<_Tp>& __y) _NOEXCEPTnoexcept
1562{
1563 __x.swap(__y);
1564}
1565
1566template<class _Tp>
1567inline
1568void
1569weak_ptr<_Tp>::reset() _NOEXCEPTnoexcept
1570{
1571 weak_ptr().swap(*this);
1572}
1573
1574template<class _Tp>
1575template<class _Yp>
1576shared_ptr<_Tp>::shared_ptr(const weak_ptr<_Yp>& __r,
1577 typename enable_if<is_convertible<_Yp*, element_type*>::value, __nat>::type)
1578 : __ptr_(__r.__ptr_),
1579 __cntrl_(__r.__cntrl_ ? __r.__cntrl_->lock() : __r.__cntrl_)
1580{
1581 if (__cntrl_ == nullptr)
1582 __throw_bad_weak_ptr();
1583}
1584
1585template<class _Tp>
1586shared_ptr<_Tp>
1587weak_ptr<_Tp>::lock() const _NOEXCEPTnoexcept
1588{
1589 shared_ptr<_Tp> __r;
1590 __r.__cntrl_ = __cntrl_ ? __cntrl_->lock() : __cntrl_;
1591 if (__r.__cntrl_)
1592 __r.__ptr_ = __ptr_;
1593 return __r;
1594}
1595
1596#if _LIBCPP_STD_VER14 > 14
1597template <class _Tp = void> struct owner_less;
1598#else
1599template <class _Tp> struct owner_less;
1600#endif
1601
1602
1603_LIBCPP_SUPPRESS_DEPRECATED_PUSHGCC diagnostic push GCC diagnostic ignored "-Wdeprecated" GCC
diagnostic ignored "-Wdeprecated-declarations"
1604template <class _Tp>
1605struct _LIBCPP_TEMPLATE_VIS__attribute__ ((__type_visibility__("default"))) owner_less<shared_ptr<_Tp> >
1606#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
1607 : binary_function<shared_ptr<_Tp>, shared_ptr<_Tp>, bool>
1608#endif
1609{
1610_LIBCPP_SUPPRESS_DEPRECATED_POPGCC diagnostic pop
1611#if _LIBCPP_STD_VER14 <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
1612 _LIBCPP_DEPRECATED_IN_CXX17 typedef bool result_type;
1613 _LIBCPP_DEPRECATED_IN_CXX17 typedef shared_ptr<_Tp> first_argument_type;
1614 _LIBCPP_DEPRECATED_IN_CXX17 typedef shared_ptr<_Tp> second_argument_type;
1615#endif
1616 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
1617 bool operator()(shared_ptr<_Tp> const& __x, shared_ptr<_Tp> const& __y) const _NOEXCEPTnoexcept
1618 {return __x.owner_before(__y);}
1619 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
1620 bool operator()(shared_ptr<_Tp> const& __x, weak_ptr<_Tp> const& __y) const _NOEXCEPTnoexcept
1621 {return __x.owner_before(__y);}
1622 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
1623 bool operator()( weak_ptr<_Tp> const& __x, shared_ptr<_Tp> const& __y) const _NOEXCEPTnoexcept
1624 {return __x.owner_before(__y);}
1625};
1626
1627_LIBCPP_SUPPRESS_DEPRECATED_PUSHGCC diagnostic push GCC diagnostic ignored "-Wdeprecated" GCC
diagnostic ignored "-Wdeprecated-declarations"
1628template <class _Tp>
1629struct _LIBCPP_TEMPLATE_VIS__attribute__ ((__type_visibility__("default"))) owner_less<weak_ptr<_Tp> >
1630#if !defined(_LIBCPP_ABI_NO_BINDER_BASES)
1631 : binary_function<weak_ptr<_Tp>, weak_ptr<_Tp>, bool>
1632#endif
1633{
1634_LIBCPP_SUPPRESS_DEPRECATED_POPGCC diagnostic pop
1635#if _LIBCPP_STD_VER14 <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
1636 _LIBCPP_DEPRECATED_IN_CXX17 typedef bool result_type;
1637 _LIBCPP_DEPRECATED_IN_CXX17 typedef weak_ptr<_Tp> first_argument_type;
1638 _LIBCPP_DEPRECATED_IN_CXX17 typedef weak_ptr<_Tp> second_argument_type;
1639#endif
1640 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
1641 bool operator()( weak_ptr<_Tp> const& __x, weak_ptr<_Tp> const& __y) const _NOEXCEPTnoexcept
1642 {return __x.owner_before(__y);}
1643 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
1644 bool operator()(shared_ptr<_Tp> const& __x, weak_ptr<_Tp> const& __y) const _NOEXCEPTnoexcept
1645 {return __x.owner_before(__y);}
1646 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
1647 bool operator()( weak_ptr<_Tp> const& __x, shared_ptr<_Tp> const& __y) const _NOEXCEPTnoexcept
1648 {return __x.owner_before(__y);}
1649};
1650
1651#if _LIBCPP_STD_VER14 > 14
1652template <>
1653struct _LIBCPP_TEMPLATE_VIS__attribute__ ((__type_visibility__("default"))) owner_less<void>
1654{
1655 template <class _Tp, class _Up>
1656 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
1657 bool operator()( shared_ptr<_Tp> const& __x, shared_ptr<_Up> const& __y) const _NOEXCEPTnoexcept
1658 {return __x.owner_before(__y);}
1659 template <class _Tp, class _Up>
1660 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
1661 bool operator()( shared_ptr<_Tp> const& __x, weak_ptr<_Up> const& __y) const _NOEXCEPTnoexcept
1662 {return __x.owner_before(__y);}
1663 template <class _Tp, class _Up>
1664 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
1665 bool operator()( weak_ptr<_Tp> const& __x, shared_ptr<_Up> const& __y) const _NOEXCEPTnoexcept
1666 {return __x.owner_before(__y);}
1667 template <class _Tp, class _Up>
1668 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
1669 bool operator()( weak_ptr<_Tp> const& __x, weak_ptr<_Up> const& __y) const _NOEXCEPTnoexcept
1670 {return __x.owner_before(__y);}
1671 typedef void is_transparent;
1672};
1673#endif
1674
1675template<class _Tp>
1676class _LIBCPP_TEMPLATE_VIS__attribute__ ((__type_visibility__("default"))) enable_shared_from_this
1677{
1678 mutable weak_ptr<_Tp> __weak_this_;
1679protected:
1680 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
_LIBCPP_CONSTEXPRconstexpr
1681 enable_shared_from_this() _NOEXCEPTnoexcept {}
1682 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
1683 enable_shared_from_this(enable_shared_from_this const&) _NOEXCEPTnoexcept {}
1684 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
1685 enable_shared_from_this& operator=(enable_shared_from_this const&) _NOEXCEPTnoexcept
1686 {return *this;}
1687 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
1688 ~enable_shared_from_this() {}
1689public:
1690 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
1691 shared_ptr<_Tp> shared_from_this()
1692 {return shared_ptr<_Tp>(__weak_this_);}
1693 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
1694 shared_ptr<_Tp const> shared_from_this() const
1695 {return shared_ptr<const _Tp>(__weak_this_);}
1696
1697#if _LIBCPP_STD_VER14 > 14
1698 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
1699 weak_ptr<_Tp> weak_from_this() _NOEXCEPTnoexcept
1700 { return __weak_this_; }
1701
1702 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
1703 weak_ptr<const _Tp> weak_from_this() const _NOEXCEPTnoexcept
1704 { return __weak_this_; }
1705#endif // _LIBCPP_STD_VER > 14
1706
1707 template <class _Up> friend class shared_ptr;
1708};
1709
1710template <class _Tp> struct _LIBCPP_TEMPLATE_VIS__attribute__ ((__type_visibility__("default"))) hash;
1711
1712template <class _Tp>
1713struct _LIBCPP_TEMPLATE_VIS__attribute__ ((__type_visibility__("default"))) hash<shared_ptr<_Tp> >
1714{
1715#if _LIBCPP_STD_VER14 <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
1716 _LIBCPP_DEPRECATED_IN_CXX17 typedef shared_ptr<_Tp> argument_type;
1717 _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type;
1718#endif
1719
1720 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
1721 size_t operator()(const shared_ptr<_Tp>& __ptr) const _NOEXCEPTnoexcept
1722 {
1723 return hash<typename shared_ptr<_Tp>::element_type*>()(__ptr.get());
1724 }
1725};
1726
1727template<class _CharT, class _Traits, class _Yp>
1728inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
1729basic_ostream<_CharT, _Traits>&
1730operator<<(basic_ostream<_CharT, _Traits>& __os, shared_ptr<_Yp> const& __p);
1731
1732
1733#if !defined(_LIBCPP_HAS_NO_ATOMIC_HEADER)
1734
1735class _LIBCPP_TYPE_VIS__attribute__ ((__visibility__("default"))) __sp_mut
1736{
1737 void* __lx;
1738public:
1739 void lock() _NOEXCEPTnoexcept;
1740 void unlock() _NOEXCEPTnoexcept;
1741
1742private:
1743 _LIBCPP_CONSTEXPRconstexpr __sp_mut(void*) _NOEXCEPTnoexcept;
1744 __sp_mut(const __sp_mut&);
1745 __sp_mut& operator=(const __sp_mut&);
1746
1747 friend _LIBCPP_FUNC_VIS__attribute__ ((__visibility__("default"))) __sp_mut& __get_sp_mut(const void*);
1748};
1749
1750_LIBCPP_FUNC_VIS__attribute__ ((__visibility__("default"))) _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
1751__sp_mut& __get_sp_mut(const void*);
1752
1753template <class _Tp>
1754inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
1755bool
1756atomic_is_lock_free(const shared_ptr<_Tp>*)
1757{
1758 return false;
1759}
1760
1761template <class _Tp>
1762_LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
1763shared_ptr<_Tp>
1764atomic_load(const shared_ptr<_Tp>* __p)
1765{
1766 __sp_mut& __m = __get_sp_mut(__p);
1767 __m.lock();
1768 shared_ptr<_Tp> __q = *__p;
1769 __m.unlock();
1770 return __q;
1771}
1772
1773template <class _Tp>
1774inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
1775_LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
1776shared_ptr<_Tp>
1777atomic_load_explicit(const shared_ptr<_Tp>* __p, memory_order)
1778{
1779 return atomic_load(__p);
1780}
1781
1782template <class _Tp>
1783_LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
1784void
1785atomic_store(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r)
1786{
1787 __sp_mut& __m = __get_sp_mut(__p);
1788 __m.lock();
1789 __p->swap(__r);
1790 __m.unlock();
1791}
1792
1793template <class _Tp>
1794inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
1795_LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
1796void
1797atomic_store_explicit(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r, memory_order)
1798{
1799 atomic_store(__p, __r);
1800}
1801
1802template <class _Tp>
1803_LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
1804shared_ptr<_Tp>
1805atomic_exchange(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r)
1806{
1807 __sp_mut& __m = __get_sp_mut(__p);
1808 __m.lock();
1809 __p->swap(__r);
1810 __m.unlock();
1811 return __r;
1812}
1813
1814template <class _Tp>
1815inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
1816_LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
1817shared_ptr<_Tp>
1818atomic_exchange_explicit(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r, memory_order)
1819{
1820 return atomic_exchange(__p, __r);
1821}
1822
1823template <class _Tp>
1824_LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
1825bool
1826atomic_compare_exchange_strong(shared_ptr<_Tp>* __p, shared_ptr<_Tp>* __v, shared_ptr<_Tp> __w)
1827{
1828 shared_ptr<_Tp> __temp;
1829 __sp_mut& __m = __get_sp_mut(__p);
1830 __m.lock();
1831 if (__p->__owner_equivalent(*__v))
1832 {
1833 _VSTDstd::__1::swap(__temp, *__p);
1834 *__p = __w;
1835 __m.unlock();
1836 return true;
1837 }
1838 _VSTDstd::__1::swap(__temp, *__v);
1839 *__v = *__p;
1840 __m.unlock();
1841 return false;
1842}
1843
1844template <class _Tp>
1845inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
1846_LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
1847bool
1848atomic_compare_exchange_weak(shared_ptr<_Tp>* __p, shared_ptr<_Tp>* __v, shared_ptr<_Tp> __w)
1849{
1850 return atomic_compare_exchange_strong(__p, __v, __w);
1851}
1852
1853template <class _Tp>
1854inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
1855_LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
1856bool
1857atomic_compare_exchange_strong_explicit(shared_ptr<_Tp>* __p, shared_ptr<_Tp>* __v,
1858 shared_ptr<_Tp> __w, memory_order, memory_order)
1859{
1860 return atomic_compare_exchange_strong(__p, __v, __w);
1861}
1862
1863template <class _Tp>
1864inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
1865_LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR
1866bool
1867atomic_compare_exchange_weak_explicit(shared_ptr<_Tp>* __p, shared_ptr<_Tp>* __v,
1868 shared_ptr<_Tp> __w, memory_order, memory_order)
1869{
1870 return atomic_compare_exchange_weak(__p, __v, __w);
1871}
1872
1873#endif // !defined(_LIBCPP_HAS_NO_ATOMIC_HEADER)
1874
1875_LIBCPP_END_NAMESPACE_STD} }
1876
1877_LIBCPP_POP_MACROSpop_macro("min") pop_macro("max")
1878
1879#endif // _LIBCPP___MEMORY_SHARED_PTR_H

/usr/src/gnu/usr.bin/clang/liblldbPluginSymbolFile/../../../llvm/lldb/include/lldb/lldb-enumerations.h

1//===-- lldb-enumerations.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_LLDB_ENUMERATIONS_H
10#define LLDB_LLDB_ENUMERATIONS_H
11
12#include <type_traits>
13
14#ifndef SWIG
15// Macro to enable bitmask operations on an enum. Without this, Enum | Enum
16// gets promoted to an int, so you have to say Enum a = Enum(eFoo | eBar). If
17// you mark Enum with LLDB_MARK_AS_BITMASK_ENUM(Enum), however, you can simply
18// write Enum a = eFoo | eBar.
19// Unfortunately, swig<3.0 doesn't recognise the constexpr keyword, so remove
20// this entire block, as it is not necessary for swig processing.
21#define LLDB_MARK_AS_BITMASK_ENUM(Enum)constexpr Enum operator|(Enum a, Enum b) { return static_cast
<Enum>( static_cast<std::underlying_type<Enum>
::type>(a) | static_cast<std::underlying_type<Enum>
::type>(b)); } constexpr Enum operator&(Enum a, Enum b
) { return static_cast<Enum>( static_cast<std::underlying_type
<Enum>::type>(a) & static_cast<std::underlying_type
<Enum>::type>(b)); } constexpr Enum operator~(Enum a
) { return static_cast<Enum>( ~static_cast<std::underlying_type
<Enum>::type>(a)); } inline Enum &operator|=(Enum
&a, Enum b) { a = a | b; return a; } inline Enum &operator
&=(Enum &a, Enum b) { a = a & b; return a; }
\
22 constexpr Enum operator|(Enum a, Enum b) { \
23 return static_cast<Enum>( \
24 static_cast<std::underlying_type<Enum>::type>(a) | \
25 static_cast<std::underlying_type<Enum>::type>(b)); \
26 } \
27 constexpr Enum operator&(Enum a, Enum b) { \
28 return static_cast<Enum>( \
29 static_cast<std::underlying_type<Enum>::type>(a) & \
30 static_cast<std::underlying_type<Enum>::type>(b)); \
31 } \
32 constexpr Enum operator~(Enum a) { \
33 return static_cast<Enum>( \
34 ~static_cast<std::underlying_type<Enum>::type>(a)); \
35 } \
36 inline Enum &operator|=(Enum &a, Enum b) { \
37 a = a | b; \
38 return a; \
39 } \
40 inline Enum &operator&=(Enum &a, Enum b) { \
41 a = a & b; \
42 return a; \
43 }
44#else
45#define LLDB_MARK_AS_BITMASK_ENUM(Enum)constexpr Enum operator|(Enum a, Enum b) { return static_cast
<Enum>( static_cast<std::underlying_type<Enum>
::type>(a) | static_cast<std::underlying_type<Enum>
::type>(b)); } constexpr Enum operator&(Enum a, Enum b
) { return static_cast<Enum>( static_cast<std::underlying_type
<Enum>::type>(a) & static_cast<std::underlying_type
<Enum>::type>(b)); } constexpr Enum operator~(Enum a
) { return static_cast<Enum>( ~static_cast<std::underlying_type
<Enum>::type>(a)); } inline Enum &operator|=(Enum
&a, Enum b) { a = a | b; return a; } inline Enum &operator
&=(Enum &a, Enum b) { a = a & b; return a; }
46#endif
47
48#ifndef SWIG
49// With MSVC, the default type of an enum is always signed, even if one of the
50// enumerator values is too large to fit into a signed integer but would
51// otherwise fit into an unsigned integer. As a result of this, all of LLDB's
52// flag-style enumerations that specify something like eValueFoo = 1u << 31
53// result in negative values. This usually just results in a benign warning,
54// but in a few places we actually do comparisons on the enum values, which
55// would cause a real bug. Furthermore, there's no way to silence only this
56// warning, as it's part of -Wmicrosoft which also catches a whole slew of
57// other useful issues.
58//
59// To make matters worse, early versions of SWIG don't recognize the syntax of
60// specifying the underlying type of an enum (and Python doesn't care anyway)
61// so we need a way to specify the underlying type when the enum is being used
62// from C++ code, but just use a regular enum when swig is pre-processing.
63#define FLAGS_ENUM(Name)enum Name : unsigned enum Name : unsigned
64#define FLAGS_ANONYMOUS_ENUM()enum : unsigned enum : unsigned
65#else
66#define FLAGS_ENUM(Name)enum Name : unsigned enum Name
67#define FLAGS_ANONYMOUS_ENUM()enum : unsigned enum
68#endif
69
70namespace lldb {
71
72/// Process and Thread States.
73enum StateType {
74 eStateInvalid = 0,
75 eStateUnloaded, ///< Process is object is valid, but not currently loaded
76 eStateConnected, ///< Process is connected to remote debug services, but not
77 /// launched or attached to anything yet
78 eStateAttaching, ///< Process is currently trying to attach
79 eStateLaunching, ///< Process is in the process of launching
80 // The state changes eStateAttaching and eStateLaunching are both sent while
81 // the private state thread is either not yet started or paused. For that
82 // reason, they should only be signaled as public state changes, and not
83 // private state changes.
84 eStateStopped, ///< Process or thread is stopped and can be examined.
85 eStateRunning, ///< Process or thread is running and can't be examined.
86 eStateStepping, ///< Process or thread is in the process of stepping and can
87 /// not be examined.
88 eStateCrashed, ///< Process or thread has crashed and can be examined.
89 eStateDetached, ///< Process has been detached and can't be examined.
90 eStateExited, ///< Process has exited and can't be examined.
91 eStateSuspended, ///< Process or thread is in a suspended state as far
92 ///< as the debugger is concerned while other processes
93 ///< or threads get the chance to run.
94 kLastStateType = eStateSuspended
95};
96
97/// Launch Flags.
98FLAGS_ENUM(LaunchFlags)enum LaunchFlags : unsigned{
99 eLaunchFlagNone = 0u,
100 eLaunchFlagExec = (1u << 0), ///< Exec when launching and turn the calling
101 /// process into a new process
102 eLaunchFlagDebug = (1u << 1), ///< Stop as soon as the process launches to
103 /// allow the process to be debugged
104 eLaunchFlagStopAtEntry = (1u
105 << 2), ///< Stop at the program entry point
106 /// instead of auto-continuing when
107 /// launching or attaching at entry point
108 eLaunchFlagDisableASLR =
109 (1u << 3), ///< Disable Address Space Layout Randomization
110 eLaunchFlagDisableSTDIO =
111 (1u << 4), ///< Disable stdio for inferior process (e.g. for a GUI app)
112 eLaunchFlagLaunchInTTY =
113 (1u << 5), ///< Launch the process in a new TTY if supported by the host
114 eLaunchFlagLaunchInShell =
115 (1u << 6), ///< Launch the process inside a shell to get shell expansion
116 eLaunchFlagLaunchInSeparateProcessGroup =
117 (1u << 7), ///< Launch the process in a separate process group
118 ///< If you are going to hand the process off (e.g. to
119 ///< debugserver)
120 eLaunchFlagDontSetExitStatus = (1u << 8),
121 ///< set this flag so lldb & the handee don't race to set its exit status.
122 eLaunchFlagDetachOnError = (1u << 9), ///< If set, then the client stub
123 ///< should detach rather than killing
124 ///< the debugee
125 ///< if it loses connection with lldb.
126 eLaunchFlagShellExpandArguments =
127 (1u << 10), ///< Perform shell-style argument expansion
128 eLaunchFlagCloseTTYOnExit = (1u << 11), ///< Close the open TTY on exit
129 eLaunchFlagInheritTCCFromParent =
130 (1u << 12), ///< Don't make the inferior responsible for its own TCC
131 ///< permissions but instead inherit them from its parent.
132};
133
134/// Thread Run Modes.
135enum RunMode { eOnlyThisThread, eAllThreads, eOnlyDuringStepping };
136
137/// Byte ordering definitions.
138enum ByteOrder {
139 eByteOrderInvalid = 0,
140 eByteOrderBig = 1,
141 eByteOrderPDP = 2,
142 eByteOrderLittle = 4
143};
144
145/// Register encoding definitions.
146enum Encoding {
147 eEncodingInvalid = 0,
148 eEncodingUint, ///< unsigned integer
149 eEncodingSint, ///< signed integer
150 eEncodingIEEE754, ///< float
151 eEncodingVector ///< vector registers
152};
153
154/// Display format definitions.
155enum Format {
156 eFormatDefault = 0,
157 eFormatInvalid = 0,
158 eFormatBoolean,
159 eFormatBinary,
160 eFormatBytes,
161 eFormatBytesWithASCII,
162 eFormatChar,
163 eFormatCharPrintable, ///< Only printable characters, '.' if not printable
164 eFormatComplex, ///< Floating point complex type
165 eFormatComplexFloat = eFormatComplex,
166 eFormatCString, ///< NULL terminated C strings
167 eFormatDecimal,
168 eFormatEnum,
169 eFormatHex,
170 eFormatHexUppercase,
171 eFormatFloat,
172 eFormatOctal,
173 eFormatOSType, ///< OS character codes encoded into an integer 'PICT' 'text'
174 ///< etc...
175 eFormatUnicode16,
176 eFormatUnicode32,
177 eFormatUnsigned,
178 eFormatPointer,
179 eFormatVectorOfChar,
180 eFormatVectorOfSInt8,
181 eFormatVectorOfUInt8,
182 eFormatVectorOfSInt16,
183 eFormatVectorOfUInt16,
184 eFormatVectorOfSInt32,
185 eFormatVectorOfUInt32,
186 eFormatVectorOfSInt64,
187 eFormatVectorOfUInt64,
188 eFormatVectorOfFloat16,
189 eFormatVectorOfFloat32,
190 eFormatVectorOfFloat64,
191 eFormatVectorOfUInt128,
192 eFormatComplexInteger, ///< Integer complex type
193 eFormatCharArray, ///< Print characters with no single quotes, used for
194 ///< character arrays that can contain non printable
195 ///< characters
196 eFormatAddressInfo, ///< Describe what an address points to (func + offset
197 ///< with file/line, symbol + offset, data, etc)
198 eFormatHexFloat, ///< ISO C99 hex float string
199 eFormatInstruction, ///< Disassemble an opcode
200 eFormatVoid, ///< Do not print this
201 eFormatUnicode8,
202 kNumFormats
203};
204
205/// Description levels for "void GetDescription(Stream *, DescriptionLevel)"
206/// calls.
207enum DescriptionLevel {
208 eDescriptionLevelBrief = 0,
209 eDescriptionLevelFull,
210 eDescriptionLevelVerbose,
211 eDescriptionLevelInitial,
212 kNumDescriptionLevels
213};
214
215/// Script interpreter types.
216enum ScriptLanguage {
217 eScriptLanguageNone = 0,
218 eScriptLanguagePython,
219 eScriptLanguageLua,
220 eScriptLanguageUnknown,
221 eScriptLanguageDefault = eScriptLanguagePython
222};
223
224/// Register numbering types.
225// See RegisterContext::ConvertRegisterKindToRegisterNumber to convert any of
226// these to the lldb internal register numbering scheme (eRegisterKindLLDB).
227enum RegisterKind {
228 eRegisterKindEHFrame = 0, ///< the register numbers seen in eh_frame
229 eRegisterKindDWARF, ///< the register numbers seen DWARF
230 eRegisterKindGeneric, ///< insn ptr reg, stack ptr reg, etc not specific to
231 ///< any particular target
232 eRegisterKindProcessPlugin, ///< num used by the process plugin - e.g. by the
233 ///< remote gdb-protocol stub program
234 eRegisterKindLLDB, ///< lldb's internal register numbers
235 kNumRegisterKinds
236};
237
238/// Thread stop reasons.
239enum StopReason {
240 eStopReasonInvalid = 0,
241 eStopReasonNone,
242 eStopReasonTrace,
243 eStopReasonBreakpoint,
244 eStopReasonWatchpoint,
245 eStopReasonSignal,
246 eStopReasonException,
247 eStopReasonExec, ///< Program was re-exec'ed
248 eStopReasonPlanComplete,
249 eStopReasonThreadExiting,
250 eStopReasonInstrumentation,
251 eStopReasonProcessorTrace,
252 eStopReasonFork,
253 eStopReasonVFork,
254 eStopReasonVForkDone,
255};
256
257/// Command Return Status Types.
258enum ReturnStatus {
259 eReturnStatusInvalid,
260 eReturnStatusSuccessFinishNoResult,
261 eReturnStatusSuccessFinishResult,
262 eReturnStatusSuccessContinuingNoResult,
263 eReturnStatusSuccessContinuingResult,
264 eReturnStatusStarted,
265 eReturnStatusFailed,
266 eReturnStatusQuit
267};
268
269/// The results of expression evaluation.
270enum ExpressionResults {
271 eExpressionCompleted = 0,
272 eExpressionSetupError,
273 eExpressionParseError,
274 eExpressionDiscarded,
275 eExpressionInterrupted,
276 eExpressionHitBreakpoint,
277 eExpressionTimedOut,
278 eExpressionResultUnavailable,
279 eExpressionStoppedForDebug,
280 eExpressionThreadVanished
281};
282
283enum SearchDepth {
284 eSearchDepthInvalid = 0,
285 eSearchDepthTarget,
286 eSearchDepthModule,
287 eSearchDepthCompUnit,
288 eSearchDepthFunction,
289 eSearchDepthBlock,
290 eSearchDepthAddress,
291 kLastSearchDepthKind = eSearchDepthAddress
292};
293
294/// Connection Status Types.
295enum ConnectionStatus {
296 eConnectionStatusSuccess, ///< Success
297 eConnectionStatusEndOfFile, ///< End-of-file encountered
298 eConnectionStatusError, ///< Check GetError() for details
299 eConnectionStatusTimedOut, ///< Request timed out
300 eConnectionStatusNoConnection, ///< No connection
301 eConnectionStatusLostConnection, ///< Lost connection while connected to a
302 ///< valid connection
303 eConnectionStatusInterrupted ///< Interrupted read
304};
305
306enum ErrorType {
307 eErrorTypeInvalid,
308 eErrorTypeGeneric, ///< Generic errors that can be any value.
309 eErrorTypeMachKernel, ///< Mach kernel error codes.
310 eErrorTypePOSIX, ///< POSIX error codes.
311 eErrorTypeExpression, ///< These are from the ExpressionResults enum.
312 eErrorTypeWin32 ///< Standard Win32 error codes.
313};
314
315enum ValueType {
316 eValueTypeInvalid = 0,
317 eValueTypeVariableGlobal = 1, ///< globals variable
318 eValueTypeVariableStatic = 2, ///< static variable
319 eValueTypeVariableArgument = 3, ///< function argument variables
320 eValueTypeVariableLocal = 4, ///< function local variables
321 eValueTypeRegister = 5, ///< stack frame register value
322 eValueTypeRegisterSet = 6, ///< A collection of stack frame register values
323 eValueTypeConstResult = 7, ///< constant result variables
324 eValueTypeVariableThreadLocal = 8 ///< thread local storage variable
325};
326
327/// Token size/granularities for Input Readers.
328
329enum InputReaderGranularity {
330 eInputReaderGranularityInvalid = 0,
331 eInputReaderGranularityByte,
332 eInputReaderGranularityWord,
333 eInputReaderGranularityLine,
334 eInputReaderGranularityAll
335};
336
337/// These mask bits allow a common interface for queries that can
338/// limit the amount of information that gets parsed to only the
339/// information that is requested. These bits also can indicate what
340/// actually did get resolved during query function calls.
341///
342/// Each definition corresponds to a one of the member variables
343/// in this class, and requests that that item be resolved, or
344/// indicates that the member did get resolved.
345FLAGS_ENUM(SymbolContextItem)enum SymbolContextItem : unsigned{
346 /// Set when \a target is requested from a query, or was located
347 /// in query results
348 eSymbolContextTarget = (1u << 0),
349 /// Set when \a module is requested from a query, or was located
350 /// in query results
351 eSymbolContextModule = (1u << 1),
352 /// Set when \a comp_unit is requested from a query, or was
353 /// located in query results
354 eSymbolContextCompUnit = (1u << 2),
355 /// Set when \a function is requested from a query, or was located
356 /// in query results
357 eSymbolContextFunction = (1u << 3),
358 /// Set when the deepest \a block is requested from a query, or
359 /// was located in query results
360 eSymbolContextBlock = (1u << 4),
361 /// Set when \a line_entry is requested from a query, or was
362 /// located in query results
363 eSymbolContextLineEntry = (1u << 5),
364 /// Set when \a symbol is requested from a query, or was located
365 /// in query results
366 eSymbolContextSymbol = (1u << 6),
367 /// Indicates to try and lookup everything up during a routine
368 /// symbol context query.
369 eSymbolContextEverything = ((eSymbolContextSymbol << 1) - 1u),
370 /// Set when \a global or static variable is requested from a
371 /// query, or was located in query results.
372 /// eSymbolContextVariable is potentially expensive to lookup so
373 /// it isn't included in eSymbolContextEverything which stops it
374 /// from being used during frame PC lookups and many other
375 /// potential address to symbol context lookups.
376 eSymbolContextVariable = (1u << 7),
377};
378LLDB_MARK_AS_BITMASK_ENUM(SymbolContextItem)constexpr SymbolContextItem operator|(SymbolContextItem a, SymbolContextItem
b) { return static_cast<SymbolContextItem>( static_cast
<std::underlying_type<SymbolContextItem>::type>(a
) | static_cast<std::underlying_type<SymbolContextItem>
::type>(b)); } constexpr SymbolContextItem operator&(SymbolContextItem
a, SymbolContextItem b) { return static_cast<SymbolContextItem
>( static_cast<std::underlying_type<SymbolContextItem
>::type>(a) & static_cast<std::underlying_type<
SymbolContextItem>::type>(b)); } constexpr SymbolContextItem
operator~(SymbolContextItem a) { return static_cast<SymbolContextItem
>( ~static_cast<std::underlying_type<SymbolContextItem
>::type>(a)); } inline SymbolContextItem &operator|=
(SymbolContextItem &a, SymbolContextItem b) { a = a | b; return
a; } inline SymbolContextItem &operator&=(SymbolContextItem
&a, SymbolContextItem b) { a = a & b; return a; }
11
Returning zero, which participates in a condition later
379
380FLAGS_ENUM(Permissions)enum Permissions : unsigned{ePermissionsWritable = (1u << 0),
381 ePermissionsReadable = (1u << 1),
382 ePermissionsExecutable = (1u << 2)};
383LLDB_MARK_AS_BITMASK_ENUM(Permissions)constexpr Permissions operator|(Permissions a, Permissions b)
{ return static_cast<Permissions>( static_cast<std::
underlying_type<Permissions>::type>(a) | static_cast
<std::underlying_type<Permissions>::type>(b)); } constexpr
Permissions operator&(Permissions a, Permissions b) { return
static_cast<Permissions>( static_cast<std::underlying_type
<Permissions>::type>(a) & static_cast<std::underlying_type
<Permissions>::type>(b)); } constexpr Permissions operator
~(Permissions a) { return static_cast<Permissions>( ~static_cast
<std::underlying_type<Permissions>::type>(a)); } inline
Permissions &operator|=(Permissions &a, Permissions b
) { a = a | b; return a; } inline Permissions &operator&=
(Permissions &a, Permissions b) { a = a & b; return a
; }
384
385enum InputReaderAction {
386 eInputReaderActivate, ///< reader is newly pushed onto the reader stack
387 eInputReaderAsynchronousOutputWritten, ///< an async output event occurred;
388 ///< the reader may want to do
389 ///< something
390 eInputReaderReactivate, ///< reader is on top of the stack again after another
391 ///< reader was popped off
392 eInputReaderDeactivate, ///< another reader was pushed on the stack
393 eInputReaderGotToken, ///< reader got one of its tokens (granularity)
394 eInputReaderInterrupt, ///< reader received an interrupt signal (probably from
395 ///< a control-c)
396 eInputReaderEndOfFile, ///< reader received an EOF char (probably from a
397 ///< control-d)
398 eInputReaderDone ///< reader was just popped off the stack and is done
399};
400
401FLAGS_ENUM(BreakpointEventType)enum BreakpointEventType : unsigned{
402 eBreakpointEventTypeInvalidType = (1u << 0),
403 eBreakpointEventTypeAdded = (1u << 1),
404 eBreakpointEventTypeRemoved = (1u << 2),
405 eBreakpointEventTypeLocationsAdded = (1u << 3), ///< Locations added doesn't
406 ///< get sent when the
407 ///< breakpoint is created
408 eBreakpointEventTypeLocationsRemoved = (1u << 4),
409 eBreakpointEventTypeLocationsResolved = (1u << 5),
410 eBreakpointEventTypeEnabled = (1u << 6),
411 eBreakpointEventTypeDisabled = (1u << 7),
412 eBreakpointEventTypeCommandChanged = (1u << 8),
413 eBreakpointEventTypeConditionChanged = (1u << 9),
414 eBreakpointEventTypeIgnoreChanged = (1u << 10),
415 eBreakpointEventTypeThreadChanged = (1u << 11),
416 eBreakpointEventTypeAutoContinueChanged = (1u << 12)};
417
418FLAGS_ENUM(WatchpointEventType)enum WatchpointEventType : unsigned{
419 eWatchpointEventTypeInvalidType = (1u << 0),
420 eWatchpointEventTypeAdded = (1u << 1),
421 eWatchpointEventTypeRemoved = (1u << 2),
422 eWatchpointEventTypeEnabled = (1u << 6),
423 eWatchpointEventTypeDisabled = (1u << 7),
424 eWatchpointEventTypeCommandChanged = (1u << 8),
425 eWatchpointEventTypeConditionChanged = (1u << 9),
426 eWatchpointEventTypeIgnoreChanged = (1u << 10),
427 eWatchpointEventTypeThreadChanged = (1u << 11),
428 eWatchpointEventTypeTypeChanged = (1u << 12)};
429
430/// Programming language type.
431///
432/// These enumerations use the same language enumerations as the DWARF
433/// specification for ease of use and consistency.
434/// The enum -> string code is in Language.cpp, don't change this
435/// table without updating that code as well.
436enum LanguageType {
437 eLanguageTypeUnknown = 0x0000, ///< Unknown or invalid language value.
438 eLanguageTypeC89 = 0x0001, ///< ISO C:1989.
439 eLanguageTypeC = 0x0002, ///< Non-standardized C, such as K&R.
440 eLanguageTypeAda83 = 0x0003, ///< ISO Ada:1983.
441 eLanguageTypeC_plus_plus = 0x0004, ///< ISO C++:1998.
442 eLanguageTypeCobol74 = 0x0005, ///< ISO Cobol:1974.
443 eLanguageTypeCobol85 = 0x0006, ///< ISO Cobol:1985.
444 eLanguageTypeFortran77 = 0x0007, ///< ISO Fortran 77.
445 eLanguageTypeFortran90 = 0x0008, ///< ISO Fortran 90.
446 eLanguageTypePascal83 = 0x0009, ///< ISO Pascal:1983.
447 eLanguageTypeModula2 = 0x000a, ///< ISO Modula-2:1996.
448 eLanguageTypeJava = 0x000b, ///< Java.
449 eLanguageTypeC99 = 0x000c, ///< ISO C:1999.
450 eLanguageTypeAda95 = 0x000d, ///< ISO Ada:1995.
451 eLanguageTypeFortran95 = 0x000e, ///< ISO Fortran 95.
452 eLanguageTypePLI = 0x000f, ///< ANSI PL/I:1976.
453 eLanguageTypeObjC = 0x0010, ///< Objective-C.
454 eLanguageTypeObjC_plus_plus = 0x0011, ///< Objective-C++.
455 eLanguageTypeUPC = 0x0012, ///< Unified Parallel C.
456 eLanguageTypeD = 0x0013, ///< D.
457 eLanguageTypePython = 0x0014, ///< Python.
458 // NOTE: The below are DWARF5 constants, subject to change upon
459 // completion of the DWARF5 specification
460 eLanguageTypeOpenCL = 0x0015, ///< OpenCL.
461 eLanguageTypeGo = 0x0016, ///< Go.
462 eLanguageTypeModula3 = 0x0017, ///< Modula 3.
463 eLanguageTypeHaskell = 0x0018, ///< Haskell.
464 eLanguageTypeC_plus_plus_03 = 0x0019, ///< ISO C++:2003.
465 eLanguageTypeC_plus_plus_11 = 0x001a, ///< ISO C++:2011.
466 eLanguageTypeOCaml = 0x001b, ///< OCaml.
467 eLanguageTypeRust = 0x001c, ///< Rust.
468 eLanguageTypeC11 = 0x001d, ///< ISO C:2011.
469 eLanguageTypeSwift = 0x001e, ///< Swift.
470 eLanguageTypeJulia = 0x001f, ///< Julia.
471 eLanguageTypeDylan = 0x0020, ///< Dylan.
472 eLanguageTypeC_plus_plus_14 = 0x0021, ///< ISO C++:2014.
473 eLanguageTypeFortran03 = 0x0022, ///< ISO Fortran 2003.
474 eLanguageTypeFortran08 = 0x0023, ///< ISO Fortran 2008.
475 // Vendor Extensions
476 // Note: Language::GetNameForLanguageType
477 // assumes these can be used as indexes into array language_names, and
478 // Language::SetLanguageFromCString and Language::AsCString assume these can
479 // be used as indexes into array g_languages.
480 eLanguageTypeMipsAssembler = 0x0024, ///< Mips_Assembler.
481 eLanguageTypeExtRenderScript = 0x0025, ///< RenderScript.
482 eNumLanguageTypes
483};
484
485enum InstrumentationRuntimeType {
486 eInstrumentationRuntimeTypeAddressSanitizer = 0x0000,
487 eInstrumentationRuntimeTypeThreadSanitizer = 0x0001,
488 eInstrumentationRuntimeTypeUndefinedBehaviorSanitizer = 0x0002,
489 eInstrumentationRuntimeTypeMainThreadChecker = 0x0003,
490 eInstrumentationRuntimeTypeSwiftRuntimeReporting = 0x0004,
491 eNumInstrumentationRuntimeTypes
492};
493
494enum DynamicValueType {
495 eNoDynamicValues = 0,
496 eDynamicCanRunTarget = 1,
497 eDynamicDontRunTarget = 2
498};
499
500enum StopShowColumn {
501 eStopShowColumnAnsiOrCaret = 0,
502 eStopShowColumnAnsi = 1,
503 eStopShowColumnCaret = 2,
504 eStopShowColumnNone = 3
505};
506
507enum AccessType {
508 eAccessNone,
509 eAccessPublic,
510 eAccessPrivate,
511 eAccessProtected,
512 eAccessPackage
513};
514
515enum CommandArgumentType {
516 eArgTypeAddress = 0,
517 eArgTypeAddressOrExpression,
518 eArgTypeAliasName,
519 eArgTypeAliasOptions,
520 eArgTypeArchitecture,
521 eArgTypeBoolean,
522 eArgTypeBreakpointID,
523 eArgTypeBreakpointIDRange,
524 eArgTypeBreakpointName,
525 eArgTypeByteSize,
526 eArgTypeClassName,
527 eArgTypeCommandName,
528 eArgTypeCount,
529 eArgTypeDescriptionVerbosity,
530 eArgTypeDirectoryName,
531 eArgTypeDisassemblyFlavor,
532 eArgTypeEndAddress,
533 eArgTypeExpression,
534 eArgTypeExpressionPath,
535 eArgTypeExprFormat,
536 eArgTypeFileLineColumn,
537 eArgTypeFilename,
538 eArgTypeFormat,
539 eArgTypeFrameIndex,
540 eArgTypeFullName,
541 eArgTypeFunctionName,
542 eArgTypeFunctionOrSymbol,
543 eArgTypeGDBFormat,
544 eArgTypeHelpText,
545 eArgTypeIndex,
546 eArgTypeLanguage,
547 eArgTypeLineNum,
548 eArgTypeLogCategory,
549 eArgTypeLogChannel,
550 eArgTypeMethod,
551 eArgTypeName,
552 eArgTypeNewPathPrefix,
553 eArgTypeNumLines,
554 eArgTypeNumberPerLine,
555 eArgTypeOffset,
556 eArgTypeOldPathPrefix,
557 eArgTypeOneLiner,
558 eArgTypePath,
559 eArgTypePermissionsNumber,
560 eArgTypePermissionsString,
561 eArgTypePid,
562 eArgTypePlugin,
563 eArgTypeProcessName,
564 eArgTypePythonClass,
565 eArgTypePythonFunction,
566 eArgTypePythonScript,
567 eArgTypeQueueName,
568 eArgTypeRegisterName,
569 eArgTypeRegularExpression,
570 eArgTypeRunArgs,
571 eArgTypeRunMode,
572 eArgTypeScriptedCommandSynchronicity,
573 eArgTypeScriptLang,
574 eArgTypeSearchWord,
575 eArgTypeSelector,
576 eArgTypeSettingIndex,
577 eArgTypeSettingKey,
578 eArgTypeSettingPrefix,
579 eArgTypeSettingVariableName,
580 eArgTypeShlibName,
581 eArgTypeSourceFile,
582 eArgTypeSortOrder,
583 eArgTypeStartAddress,
584 eArgTypeSummaryString,
585 eArgTypeSymbol,
586 eArgTypeThreadID,
587 eArgTypeThreadIndex,
588 eArgTypeThreadName,
589 eArgTypeTypeName,
590 eArgTypeUnsignedInteger,
591 eArgTypeUnixSignal,
592 eArgTypeVarName,
593 eArgTypeValue,
594 eArgTypeWidth,
595 eArgTypeNone,
596 eArgTypePlatform,
597 eArgTypeWatchpointID,
598 eArgTypeWatchpointIDRange,
599 eArgTypeWatchType,
600 eArgRawInput,
601 eArgTypeCommand,
602 eArgTypeColumnNum,
603 eArgTypeModuleUUID,
604 eArgTypeSaveCoreStyle,
605 eArgTypeLastArg // Always keep this entry as the last entry in this
606 // enumeration!!
607};
608
609/// Symbol types.
610// Symbol holds the SymbolType in a 6-bit field (m_type), so if you get over 63
611// entries you will have to resize that field.
612enum SymbolType {
613 eSymbolTypeAny = 0,
614 eSymbolTypeInvalid = 0,
615 eSymbolTypeAbsolute,
616 eSymbolTypeCode,
617 eSymbolTypeResolver,
618 eSymbolTypeData,
619 eSymbolTypeTrampoline,
620 eSymbolTypeRuntime,
621 eSymbolTypeException,
622 eSymbolTypeSourceFile,
623 eSymbolTypeHeaderFile,
624 eSymbolTypeObjectFile,
625 eSymbolTypeCommonBlock,
626 eSymbolTypeBlock,
627 eSymbolTypeLocal,
628 eSymbolTypeParam,
629 eSymbolTypeVariable,
630 eSymbolTypeVariableType,
631 eSymbolTypeLineEntry,
632 eSymbolTypeLineHeader,
633 eSymbolTypeScopeBegin,
634 eSymbolTypeScopeEnd,
635 eSymbolTypeAdditional, ///< When symbols take more than one entry, the extra
636 ///< entries get this type
637 eSymbolTypeCompiler,
638 eSymbolTypeInstrumentation,
639 eSymbolTypeUndefined,
640 eSymbolTypeObjCClass,
641 eSymbolTypeObjCMetaClass,
642 eSymbolTypeObjCIVar,
643 eSymbolTypeReExported
644};
645
646enum SectionType {
647 eSectionTypeInvalid,
648 eSectionTypeCode,
649 eSectionTypeContainer, ///< The section contains child sections
650 eSectionTypeData,
651 eSectionTypeDataCString, ///< Inlined C string data
652 eSectionTypeDataCStringPointers, ///< Pointers to C string data
653 eSectionTypeDataSymbolAddress, ///< Address of a symbol in the symbol table
654 eSectionTypeData4,
655 eSectionTypeData8,
656 eSectionTypeData16,
657 eSectionTypeDataPointers,
658 eSectionTypeDebug,
659 eSectionTypeZeroFill,
660 eSectionTypeDataObjCMessageRefs, ///< Pointer to function pointer + selector
661 eSectionTypeDataObjCCFStrings, ///< Objective-C const CFString/NSString
662 ///< objects
663 eSectionTypeDWARFDebugAbbrev,
664 eSectionTypeDWARFDebugAddr,
665 eSectionTypeDWARFDebugAranges,
666 eSectionTypeDWARFDebugCuIndex,
667 eSectionTypeDWARFDebugFrame,
668 eSectionTypeDWARFDebugInfo,
669 eSectionTypeDWARFDebugLine,
670 eSectionTypeDWARFDebugLoc,
671 eSectionTypeDWARFDebugMacInfo,
672 eSectionTypeDWARFDebugMacro,
673 eSectionTypeDWARFDebugPubNames,
674 eSectionTypeDWARFDebugPubTypes,
675 eSectionTypeDWARFDebugRanges,
676 eSectionTypeDWARFDebugStr,
677 eSectionTypeDWARFDebugStrOffsets,
678 eSectionTypeDWARFAppleNames,
679 eSectionTypeDWARFAppleTypes,
680 eSectionTypeDWARFAppleNamespaces,
681 eSectionTypeDWARFAppleObjC,
682 eSectionTypeELFSymbolTable, ///< Elf SHT_SYMTAB section
683 eSectionTypeELFDynamicSymbols, ///< Elf SHT_DYNSYM section
684 eSectionTypeELFRelocationEntries, ///< Elf SHT_REL or SHT_REL section
685 eSectionTypeELFDynamicLinkInfo, ///< Elf SHT_DYNAMIC section
686 eSectionTypeEHFrame,
687 eSectionTypeARMexidx,
688 eSectionTypeARMextab,
689 eSectionTypeCompactUnwind, ///< compact unwind section in Mach-O,
690 ///< __TEXT,__unwind_info
691 eSectionTypeGoSymtab,
692 eSectionTypeAbsoluteAddress, ///< Dummy section for symbols with absolute
693 ///< address
694 eSectionTypeDWARFGNUDebugAltLink,
695 eSectionTypeDWARFDebugTypes, ///< DWARF .debug_types section
696 eSectionTypeDWARFDebugNames, ///< DWARF v5 .debug_names
697 eSectionTypeOther,
698 eSectionTypeDWARFDebugLineStr, ///< DWARF v5 .debug_line_str
699 eSectionTypeDWARFDebugRngLists, ///< DWARF v5 .debug_rnglists
700 eSectionTypeDWARFDebugLocLists, ///< DWARF v5 .debug_loclists
701 eSectionTypeDWARFDebugAbbrevDwo,
702 eSectionTypeDWARFDebugInfoDwo,
703 eSectionTypeDWARFDebugStrDwo,
704 eSectionTypeDWARFDebugStrOffsetsDwo,
705 eSectionTypeDWARFDebugTypesDwo,
706 eSectionTypeDWARFDebugRngListsDwo,
707 eSectionTypeDWARFDebugLocDwo,
708 eSectionTypeDWARFDebugLocListsDwo,
709 eSectionTypeDWARFDebugTuIndex,
710};
711
712FLAGS_ENUM(EmulateInstructionOptions)enum EmulateInstructionOptions : unsigned{
713 eEmulateInstructionOptionNone = (0u),
714 eEmulateInstructionOptionAutoAdvancePC = (1u << 0),
715 eEmulateInstructionOptionIgnoreConditions = (1u << 1)};
716
717FLAGS_ENUM(FunctionNameType)enum FunctionNameType : unsigned{
718 eFunctionNameTypeNone = 0u,
719 eFunctionNameTypeAuto =
720 (1u << 1), ///< Automatically figure out which FunctionNameType
721 ///< bits to set based on the function name.
722 eFunctionNameTypeFull = (1u << 2), ///< The function name.
723 ///< For C this is the same as just the name of the function For C++ this is
724 ///< the mangled or demangled version of the mangled name. For ObjC this is
725 ///< the full function signature with the + or - and the square brackets and
726 ///< the class and selector
727 eFunctionNameTypeBase = (1u
728 << 3), ///< The function name only, no namespaces
729 ///< or arguments and no class
730 ///< methods or selectors will be searched.
731 eFunctionNameTypeMethod = (1u << 4), ///< Find function by method name (C++)
732 ///< with no namespace or arguments
733 eFunctionNameTypeSelector =
734 (1u << 5), ///< Find function by selector name (ObjC) names
735 eFunctionNameTypeAny =
736 eFunctionNameTypeAuto ///< DEPRECATED: use eFunctionNameTypeAuto
737};
738LLDB_MARK_AS_BITMASK_ENUM(FunctionNameType)constexpr FunctionNameType operator|(FunctionNameType a, FunctionNameType
b) { return static_cast<FunctionNameType>( static_cast
<std::underlying_type<FunctionNameType>::type>(a)
| static_cast<std::underlying_type<FunctionNameType>
::type>(b)); } constexpr FunctionNameType operator&(FunctionNameType
a, FunctionNameType b) { return static_cast<FunctionNameType
>( static_cast<std::underlying_type<FunctionNameType
>::type>(a) & static_cast<std::underlying_type<
FunctionNameType>::type>(b)); } constexpr FunctionNameType
operator~(FunctionNameType a) { return static_cast<FunctionNameType
>( ~static_cast<std::underlying_type<FunctionNameType
>::type>(a)); } inline FunctionNameType &operator|=
(FunctionNameType &a, FunctionNameType b) { a = a | b; return
a; } inline FunctionNameType &operator&=(FunctionNameType
&a, FunctionNameType b) { a = a & b; return a; }
739
740/// Basic types enumeration for the public API SBType::GetBasicType().
741enum BasicType {
742 eBasicTypeInvalid = 0,
743 eBasicTypeVoid = 1,
744 eBasicTypeChar,
745 eBasicTypeSignedChar,
746 eBasicTypeUnsignedChar,
747 eBasicTypeWChar,
748 eBasicTypeSignedWChar,
749 eBasicTypeUnsignedWChar,
750 eBasicTypeChar16,
751 eBasicTypeChar32,
752 eBasicTypeShort,
753 eBasicTypeUnsignedShort,
754 eBasicTypeInt,
755 eBasicTypeUnsignedInt,
756 eBasicTypeLong,
757 eBasicTypeUnsignedLong,
758 eBasicTypeLongLong,
759 eBasicTypeUnsignedLongLong,
760 eBasicTypeInt128,
761 eBasicTypeUnsignedInt128,
762 eBasicTypeBool,
763 eBasicTypeHalf,
764 eBasicTypeFloat,
765 eBasicTypeDouble,
766 eBasicTypeLongDouble,
767 eBasicTypeFloatComplex,
768 eBasicTypeDoubleComplex,
769 eBasicTypeLongDoubleComplex,
770 eBasicTypeObjCID,
771 eBasicTypeObjCClass,
772 eBasicTypeObjCSel,
773 eBasicTypeNullPtr,
774 eBasicTypeOther
775};
776
777/// Deprecated
778enum TraceType {
779 eTraceTypeNone = 0,
780
781 /// Intel Processor Trace
782 eTraceTypeProcessorTrace
783};
784
785enum StructuredDataType {
786 eStructuredDataTypeInvalid = -1,
787 eStructuredDataTypeNull = 0,
788 eStructuredDataTypeGeneric,
789 eStructuredDataTypeArray,
790 eStructuredDataTypeInteger,
791 eStructuredDataTypeFloat,
792 eStructuredDataTypeBoolean,
793 eStructuredDataTypeString,
794 eStructuredDataTypeDictionary
795};
796
797FLAGS_ENUM(TypeClass)enum TypeClass : unsigned{
798 eTypeClassInvalid = (0u), eTypeClassArray = (1u << 0),
799 eTypeClassBlockPointer = (1u << 1), eTypeClassBuiltin = (1u << 2),
800 eTypeClassClass = (1u << 3), eTypeClassComplexFloat = (1u << 4),
801 eTypeClassComplexInteger = (1u << 5), eTypeClassEnumeration = (1u << 6),
802 eTypeClassFunction = (1u << 7), eTypeClassMemberPointer = (1u << 8),
803 eTypeClassObjCObject = (1u << 9), eTypeClassObjCInterface = (1u << 10),
804 eTypeClassObjCObjectPointer = (1u << 11), eTypeClassPointer = (1u << 12),
805 eTypeClassReference = (1u << 13), eTypeClassStruct = (1u << 14),
806 eTypeClassTypedef = (1u << 15), eTypeClassUnion = (1u << 16),
807 eTypeClassVector = (1u << 17),
808 // Define the last type class as the MSBit of a 32 bit value
809 eTypeClassOther = (1u << 31),
810 // Define a mask that can be used for any type when finding types
811 eTypeClassAny = (0xffffffffu)};
812LLDB_MARK_AS_BITMASK_ENUM(TypeClass)constexpr TypeClass operator|(TypeClass a, TypeClass b) { return
static_cast<TypeClass>( static_cast<std::underlying_type
<TypeClass>::type>(a) | static_cast<std::underlying_type
<TypeClass>::type>(b)); } constexpr TypeClass operator
&(TypeClass a, TypeClass b) { return static_cast<TypeClass
>( static_cast<std::underlying_type<TypeClass>::type
>(a) & static_cast<std::underlying_type<TypeClass
>::type>(b)); } constexpr TypeClass operator~(TypeClass
a) { return static_cast<TypeClass>( ~static_cast<std
::underlying_type<TypeClass>::type>(a)); } inline TypeClass
&operator|=(TypeClass &a, TypeClass b) { a = a | b; return
a; } inline TypeClass &operator&=(TypeClass &a, TypeClass
b) { a = a & b; return a; }
813
814enum TemplateArgumentKind {
815 eTemplateArgumentKindNull = 0,
816 eTemplateArgumentKindType,
817 eTemplateArgumentKindDeclaration,
818 eTemplateArgumentKindIntegral,
819 eTemplateArgumentKindTemplate,
820 eTemplateArgumentKindTemplateExpansion,
821 eTemplateArgumentKindExpression,
822 eTemplateArgumentKindPack,
823 eTemplateArgumentKindNullPtr,
824};
825
826/// Options that can be set for a formatter to alter its behavior. Not
827/// all of these are applicable to all formatter types.
828FLAGS_ENUM(TypeOptions)enum TypeOptions : unsigned{eTypeOptionNone = (0u),
829 eTypeOptionCascade = (1u << 0),
830 eTypeOptionSkipPointers = (1u << 1),
831 eTypeOptionSkipReferences = (1u << 2),
832 eTypeOptionHideChildren = (1u << 3),
833 eTypeOptionHideValue = (1u << 4),
834 eTypeOptionShowOneLiner = (1u << 5),
835 eTypeOptionHideNames = (1u << 6),
836 eTypeOptionNonCacheable = (1u << 7),
837 eTypeOptionHideEmptyAggregates = (1u << 8),
838 eTypeOptionFrontEndWantsDereference = (1u << 9)};
839
840/// This is the return value for frame comparisons. If you are comparing frame
841/// A to frame B the following cases arise:
842///
843/// 1) When frame A pushes frame B (or a frame that ends up pushing
844/// B) A is Older than B.
845///
846/// 2) When frame A pushed frame B (or if frameA is on the stack
847/// but B is not) A is Younger than B.
848///
849/// 3) When frame A and frame B have the same StackID, they are
850/// Equal.
851///
852/// 4) When frame A and frame B have the same immediate parent
853/// frame, but are not equal, the comparison yields SameParent.
854///
855/// 5) If the two frames are on different threads or processes the
856/// comparison is Invalid.
857///
858/// 6) If for some reason we can't figure out what went on, we
859/// return Unknown.
860enum FrameComparison {
861 eFrameCompareInvalid,
862 eFrameCompareUnknown,
863 eFrameCompareEqual,
864 eFrameCompareSameParent,
865 eFrameCompareYounger,
866 eFrameCompareOlder
867};
868
869/// File Permissions.
870///
871/// Designed to mimic the unix file permission bits so they can be used with
872/// functions that set 'mode_t' to certain values for permissions.
873FLAGS_ENUM(FilePermissions)enum FilePermissions : unsigned{
874 eFilePermissionsUserRead = (1u << 8),
875 eFilePermissionsUserWrite = (1u << 7),
876 eFilePermissionsUserExecute = (1u << 6),
877 eFilePermissionsGroupRead = (1u << 5),
878 eFilePermissionsGroupWrite = (1u << 4),
879 eFilePermissionsGroupExecute = (1u << 3),
880 eFilePermissionsWorldRead = (1u << 2),
881 eFilePermissionsWorldWrite = (1u << 1),
882 eFilePermissionsWorldExecute = (1u << 0),
883
884 eFilePermissionsUserRW = (eFilePermissionsUserRead |
885 eFilePermissionsUserWrite | 0),
886 eFileFilePermissionsUserRX = (eFilePermissionsUserRead | 0 |
887 eFilePermissionsUserExecute),
888 eFilePermissionsUserRWX = (eFilePermissionsUserRead |
889 eFilePermissionsUserWrite |
890 eFilePermissionsUserExecute),
891
892 eFilePermissionsGroupRW = (eFilePermissionsGroupRead |
893 eFilePermissionsGroupWrite | 0),
894 eFilePermissionsGroupRX = (eFilePermissionsGroupRead | 0 |
895 eFilePermissionsGroupExecute),
896 eFilePermissionsGroupRWX = (eFilePermissionsGroupRead |
897 eFilePermissionsGroupWrite |
898 eFilePermissionsGroupExecute),
899
900 eFilePermissionsWorldRW = (eFilePermissionsWorldRead |
901 eFilePermissionsWorldWrite | 0),
902 eFilePermissionsWorldRX = (eFilePermissionsWorldRead | 0 |
903 eFilePermissionsWorldExecute),
904 eFilePermissionsWorldRWX = (eFilePermissionsWorldRead |
905 eFilePermissionsWorldWrite |
906 eFilePermissionsWorldExecute),
907
908 eFilePermissionsEveryoneR = (eFilePermissionsUserRead |
909 eFilePermissionsGroupRead |
910 eFilePermissionsWorldRead),
911 eFilePermissionsEveryoneW = (eFilePermissionsUserWrite |
912 eFilePermissionsGroupWrite |
913 eFilePermissionsWorldWrite),
914 eFilePermissionsEveryoneX = (eFilePermissionsUserExecute |
915 eFilePermissionsGroupExecute |
916 eFilePermissionsWorldExecute),
917
918 eFilePermissionsEveryoneRW = (eFilePermissionsEveryoneR |
919 eFilePermissionsEveryoneW | 0),
920 eFilePermissionsEveryoneRX = (eFilePermissionsEveryoneR | 0 |
921 eFilePermissionsEveryoneX),
922 eFilePermissionsEveryoneRWX = (eFilePermissionsEveryoneR |
923 eFilePermissionsEveryoneW |
924 eFilePermissionsEveryoneX),
925 eFilePermissionsFileDefault = eFilePermissionsUserRW,
926 eFilePermissionsDirectoryDefault = eFilePermissionsUserRWX,
927};
928
929/// Queue work item types.
930///
931/// The different types of work that can be enqueued on a libdispatch aka Grand
932/// Central Dispatch (GCD) queue.
933enum QueueItemKind {
934 eQueueItemKindUnknown = 0,
935 eQueueItemKindFunction,
936 eQueueItemKindBlock
937};
938
939/// Queue type.
940///
941/// libdispatch aka Grand Central Dispatch (GCD) queues can be either
942/// serial (executing on one thread) or concurrent (executing on
943/// multiple threads).
944enum QueueKind {
945 eQueueKindUnknown = 0,
946 eQueueKindSerial,
947 eQueueKindConcurrent
948};
949
950/// Expression Evaluation Stages.
951///
952/// These are the cancellable stages of expression evaluation, passed
953/// to the expression evaluation callback, so that you can interrupt
954/// expression evaluation at the various points in its lifecycle.
955enum ExpressionEvaluationPhase {
956 eExpressionEvaluationParse = 0,
957 eExpressionEvaluationIRGen,
958 eExpressionEvaluationExecution,
959 eExpressionEvaluationComplete
960};
961
962/// Architecture-agnostic categorization of instructions for traversing the
963/// control flow of a trace.
964///
965/// A single instruction can match one or more of these categories.
966FLAGS_ENUM(TraceInstructionControlFlowType)enum TraceInstructionControlFlowType : unsigned{
967 /// Any instruction.
968 eTraceInstructionControlFlowTypeInstruction = (1u << 1),
969 /// A conditional or unconditional branch/jump.
970 eTraceInstructionControlFlowTypeBranch = (1u << 2),
971 /// A conditional or unconditional branch/jump that changed
972 /// the control flow of the program.
973 eTraceInstructionControlFlowTypeTakenBranch = (1u << 3),
974 /// A call to a function.
975 eTraceInstructionControlFlowTypeCall = (1u << 4),
976 /// A return from a function.
977 eTraceInstructionControlFlowTypeReturn = (1u << 5)};
978
979LLDB_MARK_AS_BITMASK_ENUM(TraceInstructionControlFlowType)constexpr TraceInstructionControlFlowType operator|(TraceInstructionControlFlowType
a, TraceInstructionControlFlowType b) { return static_cast<
TraceInstructionControlFlowType>( static_cast<std::underlying_type
<TraceInstructionControlFlowType>::type>(a) | static_cast
<std::underlying_type<TraceInstructionControlFlowType>
::type>(b)); } constexpr TraceInstructionControlFlowType operator
&(TraceInstructionControlFlowType a, TraceInstructionControlFlowType
b) { return static_cast<TraceInstructionControlFlowType>
( static_cast<std::underlying_type<TraceInstructionControlFlowType
>::type>(a) & static_cast<std::underlying_type<
TraceInstructionControlFlowType>::type>(b)); } constexpr
TraceInstructionControlFlowType operator~(TraceInstructionControlFlowType
a) { return static_cast<TraceInstructionControlFlowType>
( ~static_cast<std::underlying_type<TraceInstructionControlFlowType
>::type>(a)); } inline TraceInstructionControlFlowType &
operator|=(TraceInstructionControlFlowType &a, TraceInstructionControlFlowType
b) { a = a | b; return a; } inline TraceInstructionControlFlowType
&operator&=(TraceInstructionControlFlowType &a, TraceInstructionControlFlowType
b) { a = a & b; return a; }
980
981/// Watchpoint Kind.
982///
983/// Indicates what types of events cause the watchpoint to fire. Used by Native
984/// *Protocol-related classes.
985FLAGS_ENUM(WatchpointKind)enum WatchpointKind : unsigned{eWatchpointKindWrite = (1u << 0),
986 eWatchpointKindRead = (1u << 1)};
987
988enum GdbSignal {
989 eGdbSignalBadAccess = 0x91,
990 eGdbSignalBadInstruction = 0x92,
991 eGdbSignalArithmetic = 0x93,
992 eGdbSignalEmulation = 0x94,
993 eGdbSignalSoftware = 0x95,
994 eGdbSignalBreakpoint = 0x96
995};
996
997/// Used with SBHostOS::GetLLDBPath (lldb::PathType) to find files that are
998/// related to LLDB on the current host machine. Most files are
999/// relative to LLDB or are in known locations.
1000enum PathType {
1001 ePathTypeLLDBShlibDir, ///< The directory where the lldb.so (unix) or LLDB
1002 ///< mach-o file in LLDB.framework (MacOSX) exists
1003 ePathTypeSupportExecutableDir, ///< Find LLDB support executable directory
1004 ///< (debugserver, etc)
1005 ePathTypeHeaderDir, ///< Find LLDB header file directory
1006 ePathTypePythonDir, ///< Find Python modules (PYTHONPATH) directory
1007 ePathTypeLLDBSystemPlugins, ///< System plug-ins directory
1008 ePathTypeLLDBUserPlugins, ///< User plug-ins directory
1009 ePathTypeLLDBTempSystemDir, ///< The LLDB temp directory for this system that
1010 ///< will be cleaned up on exit
1011 ePathTypeGlobalLLDBTempSystemDir, ///< The LLDB temp directory for this
1012 ///< system, NOT cleaned up on a process
1013 ///< exit.
1014 ePathTypeClangDir ///< Find path to Clang builtin headers
1015};
1016
1017/// Kind of member function.
1018///
1019/// Used by the type system.
1020enum MemberFunctionKind {
1021 eMemberFunctionKindUnknown = 0, ///< Not sure what the type of this is
1022 eMemberFunctionKindConstructor, ///< A function used to create instances
1023 eMemberFunctionKindDestructor, ///< A function used to tear down existing
1024 ///< instances
1025 eMemberFunctionKindInstanceMethod, ///< A function that applies to a specific
1026 ///< instance
1027 eMemberFunctionKindStaticMethod ///< A function that applies to a type rather
1028 ///< than any instance
1029};
1030
1031/// String matching algorithm used by SBTarget.
1032enum MatchType { eMatchTypeNormal, eMatchTypeRegex, eMatchTypeStartsWith };
1033
1034/// Bitmask that describes details about a type.
1035FLAGS_ENUM(TypeFlags)enum TypeFlags : unsigned{
1036 eTypeHasChildren = (1u << 0), eTypeHasValue = (1u << 1),
1037 eTypeIsArray = (1u << 2), eTypeIsBlock = (1u << 3),
1038 eTypeIsBuiltIn = (1u << 4), eTypeIsClass = (1u << 5),
1039 eTypeIsCPlusPlus = (1u << 6), eTypeIsEnumeration = (1u << 7),
1040 eTypeIsFuncPrototype = (1u << 8), eTypeIsMember = (1u << 9),
1041 eTypeIsObjC = (1u << 10), eTypeIsPointer = (1u << 11),
1042 eTypeIsReference = (1u << 12), eTypeIsStructUnion = (1u << 13),
1043 eTypeIsTemplate = (1u << 14), eTypeIsTypedef = (1u << 15),
1044 eTypeIsVector = (1u << 16), eTypeIsScalar = (1u << 17),
1045 eTypeIsInteger = (1u << 18), eTypeIsFloat = (1u << 19),
1046 eTypeIsComplex = (1u << 20), eTypeIsSigned = (1u << 21),
1047 eTypeInstanceIsPointer = (1u << 22)};
1048
1049FLAGS_ENUM(CommandFlags)enum CommandFlags : unsigned{
1050 /// eCommandRequiresTarget
1051 ///
1052 /// Ensures a valid target is contained in m_exe_ctx prior to executing the
1053 /// command. If a target doesn't exist or is invalid, the command will fail
1054 /// and CommandObject::GetInvalidTargetDescription() will be returned as the
1055 /// error. CommandObject subclasses can override the virtual function for
1056 /// GetInvalidTargetDescription() to provide custom strings when needed.
1057 eCommandRequiresTarget = (1u << 0),
1058 /// eCommandRequiresProcess
1059 ///
1060 /// Ensures a valid process is contained in m_exe_ctx prior to executing the
1061 /// command. If a process doesn't exist or is invalid, the command will fail
1062 /// and CommandObject::GetInvalidProcessDescription() will be returned as
1063 /// the error. CommandObject subclasses can override the virtual function
1064 /// for GetInvalidProcessDescription() to provide custom strings when
1065 /// needed.
1066 eCommandRequiresProcess = (1u << 1),
1067 /// eCommandRequiresThread
1068 ///
1069 /// Ensures a valid thread is contained in m_exe_ctx prior to executing the
1070 /// command. If a thread doesn't exist or is invalid, the command will fail
1071 /// and CommandObject::GetInvalidThreadDescription() will be returned as the
1072 /// error. CommandObject subclasses can override the virtual function for
1073 /// GetInvalidThreadDescription() to provide custom strings when needed.
1074 eCommandRequiresThread = (1u << 2),
1075 /// eCommandRequiresFrame
1076 ///
1077 /// Ensures a valid frame is contained in m_exe_ctx prior to executing the
1078 /// command. If a frame doesn't exist or is invalid, the command will fail
1079 /// and CommandObject::GetInvalidFrameDescription() will be returned as the
1080 /// error. CommandObject subclasses can override the virtual function for
1081 /// GetInvalidFrameDescription() to provide custom strings when needed.
1082 eCommandRequiresFrame = (1u << 3),
1083 /// eCommandRequiresRegContext
1084 ///
1085 /// Ensures a valid register context (from the selected frame if there is a
1086 /// frame in m_exe_ctx, or from the selected thread from m_exe_ctx) is
1087 /// available from m_exe_ctx prior to executing the command. If a target
1088 /// doesn't exist or is invalid, the command will fail and
1089 /// CommandObject::GetInvalidRegContextDescription() will be returned as the
1090 /// error. CommandObject subclasses can override the virtual function for
1091 /// GetInvalidRegContextDescription() to provide custom strings when needed.
1092 eCommandRequiresRegContext = (1u << 4),
1093 /// eCommandTryTargetAPILock
1094 ///
1095 /// Attempts to acquire the target lock if a target is selected in the
1096 /// command interpreter. If the command object fails to acquire the API
1097 /// lock, the command will fail with an appropriate error message.
1098 eCommandTryTargetAPILock = (1u << 5),
1099 /// eCommandProcessMustBeLaunched
1100 ///
1101 /// Verifies that there is a launched process in m_exe_ctx, if there isn't,
1102 /// the command will fail with an appropriate error message.
1103 eCommandProcessMustBeLaunched = (1u << 6),
1104 /// eCommandProcessMustBePaused
1105 ///
1106 /// Verifies that there is a paused process in m_exe_ctx, if there isn't,
1107 /// the command will fail with an appropriate error message.
1108 eCommandProcessMustBePaused = (1u << 7),
1109 /// eCommandProcessMustBeTraced
1110 ///
1111 /// Verifies that the process is being traced by a Trace plug-in, if it
1112 /// isn't the command will fail with an appropriate error message.
1113 eCommandProcessMustBeTraced = (1u << 8)};
1114
1115/// Whether a summary should cap how much data it returns to users or not.
1116enum TypeSummaryCapping {
1117 eTypeSummaryCapped = true,
1118 eTypeSummaryUncapped = false
1119};
1120
1121/// The result from a command interpreter run.
1122enum CommandInterpreterResult {
1123 /// Command interpreter finished successfully.
1124 eCommandInterpreterResultSuccess,
1125 /// Stopped because the corresponding option was set and the inferior
1126 /// crashed.
1127 eCommandInterpreterResultInferiorCrash,
1128 /// Stopped because the corresponding option was set and a command returned
1129 /// an error.
1130 eCommandInterpreterResultCommandError,
1131 /// Stopped because quit was requested.
1132 eCommandInterpreterResultQuitRequested,
1133};
1134
1135// Style of core file to create when calling SaveCore.
1136enum SaveCoreStyle {
1137 eSaveCoreUnspecified = 0,
1138 eSaveCoreFull = 1,
1139 eSaveCoreDirtyOnly = 2,
1140};
1141
1142} // namespace lldb
1143
1144#endif // LLDB_LLDB_ENUMERATIONS_H

/usr/include/c++/v1/__memory/unique_ptr.h

1// -*- C++ -*-
2//===----------------------------------------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP___MEMORY_UNIQUE_PTR_H
11#define _LIBCPP___MEMORY_UNIQUE_PTR_H
12
13#include <__config>
14#include <__functional_base>
15#include <__functional/hash.h>
16#include <__functional/operations.h>
17#include <__memory/allocator_traits.h> // __pointer
18#include <__memory/compressed_pair.h>
19#include <__utility/forward.h>
20#include <cstddef>
21#include <type_traits>
22#include <utility>
23
24#if _LIBCPP_STD_VER14 <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR)
25# include <__memory/auto_ptr.h>
26#endif
27
28#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
29#pragma GCC system_header
30#endif
31
32_LIBCPP_PUSH_MACROSpush_macro("min") push_macro("max")
33#include <__undef_macros>
34
35_LIBCPP_BEGIN_NAMESPACE_STDnamespace std { inline namespace __1 {
36
37template <class _Tp>
38struct _LIBCPP_TEMPLATE_VIS__attribute__ ((__type_visibility__("default"))) default_delete {
39 static_assert(!is_function<_Tp>::value,
40 "default_delete cannot be instantiated for function types");
41#ifndef _LIBCPP_CXX03_LANG
42 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
constexpr default_delete() _NOEXCEPTnoexcept = default;
43#else
44 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
default_delete() {}
45#endif
46 template <class _Up>
47 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
48 default_delete(const default_delete<_Up>&,
49 typename enable_if<is_convertible<_Up*, _Tp*>::value>::type* =
50 0) _NOEXCEPTnoexcept {}
51
52 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
void operator()(_Tp* __ptr) const _NOEXCEPTnoexcept {
53 static_assert(sizeof(_Tp) > 0,
54 "default_delete can not delete incomplete type");
55 static_assert(!is_void<_Tp>::value,
56 "default_delete can not delete incomplete type");
57 delete __ptr;
58 }
59};
60
61template <class _Tp>
62struct _LIBCPP_TEMPLATE_VIS__attribute__ ((__type_visibility__("default"))) default_delete<_Tp[]> {
63private:
64 template <class _Up>
65 struct _EnableIfConvertible
66 : enable_if<is_convertible<_Up(*)[], _Tp(*)[]>::value> {};
67
68public:
69#ifndef _LIBCPP_CXX03_LANG
70 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
constexpr default_delete() _NOEXCEPTnoexcept = default;
71#else
72 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
default_delete() {}
73#endif
74
75 template <class _Up>
76 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
77 default_delete(const default_delete<_Up[]>&,
78 typename _EnableIfConvertible<_Up>::type* = 0) _NOEXCEPTnoexcept {}
79
80 template <class _Up>
81 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
82 typename _EnableIfConvertible<_Up>::type
83 operator()(_Up* __ptr) const _NOEXCEPTnoexcept {
84 static_assert(sizeof(_Tp) > 0,
85 "default_delete can not delete incomplete type");
86 static_assert(!is_void<_Tp>::value,
87 "default_delete can not delete void type");
88 delete[] __ptr;
89 }
90};
91
92template <class _Deleter>
93struct __unique_ptr_deleter_sfinae {
94 static_assert(!is_reference<_Deleter>::value, "incorrect specialization");
95 typedef const _Deleter& __lval_ref_type;
96 typedef _Deleter&& __good_rval_ref_type;
97 typedef true_type __enable_rval_overload;
98};
99
100template <class _Deleter>
101struct __unique_ptr_deleter_sfinae<_Deleter const&> {
102 typedef const _Deleter& __lval_ref_type;
103 typedef const _Deleter&& __bad_rval_ref_type;
104 typedef false_type __enable_rval_overload;
105};
106
107template <class _Deleter>
108struct __unique_ptr_deleter_sfinae<_Deleter&> {
109 typedef _Deleter& __lval_ref_type;
110 typedef _Deleter&& __bad_rval_ref_type;
111 typedef false_type __enable_rval_overload;
112};
113
114#if defined(_LIBCPP_ABI_ENABLE_UNIQUE_PTR_TRIVIAL_ABI)
115# define _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI __attribute__((trivial_abi))
116#else
117# define _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI
118#endif
119
120template <class _Tp, class _Dp = default_delete<_Tp> >
121class _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS__attribute__ ((__type_visibility__("default"))) unique_ptr {
122public:
123 typedef _Tp element_type;
124 typedef _Dp deleter_type;
125 typedef _LIBCPP_NODEBUG_TYPE__attribute__((nodebug)) typename __pointer<_Tp, deleter_type>::type pointer;
126
127 static_assert(!is_rvalue_reference<deleter_type>::value,
128 "the specified deleter type cannot be an rvalue reference");
129
130private:
131 __compressed_pair<pointer, deleter_type> __ptr_;
132
133 struct __nat { int __for_bool_; };
134
135 typedef _LIBCPP_NODEBUG_TYPE__attribute__((nodebug)) __unique_ptr_deleter_sfinae<_Dp> _DeleterSFINAE;
136
137 template <bool _Dummy>
138 using _LValRefType _LIBCPP_NODEBUG_TYPE__attribute__((nodebug)) =
139 typename __dependent_type<_DeleterSFINAE, _Dummy>::__lval_ref_type;
140
141 template <bool _Dummy>
142 using _GoodRValRefType _LIBCPP_NODEBUG_TYPE__attribute__((nodebug)) =
143 typename __dependent_type<_DeleterSFINAE, _Dummy>::__good_rval_ref_type;
144
145 template <bool _Dummy>
146 using _BadRValRefType _LIBCPP_NODEBUG_TYPE__attribute__((nodebug)) =
147 typename __dependent_type<_DeleterSFINAE, _Dummy>::__bad_rval_ref_type;
148
149 template <bool _Dummy, class _Deleter = typename __dependent_type<
150 __identity<deleter_type>, _Dummy>::type>
151 using _EnableIfDeleterDefaultConstructible _LIBCPP_NODEBUG_TYPE__attribute__((nodebug)) =
152 typename enable_if<is_default_constructible<_Deleter>::value &&
153 !is_pointer<_Deleter>::value>::type;
154
155 template <class _ArgType>
156 using _EnableIfDeleterConstructible _LIBCPP_NODEBUG_TYPE__attribute__((nodebug)) =
157 typename enable_if<is_constructible<deleter_type, _ArgType>::value>::type;
158
159 template <class _UPtr, class _Up>
160 using _EnableIfMoveConvertible _LIBCPP_NODEBUG_TYPE__attribute__((nodebug)) = typename enable_if<
161 is_convertible<typename _UPtr::pointer, pointer>::value &&
162 !is_array<_Up>::value
163 >::type;
164
165 template <class _UDel>
166 using _EnableIfDeleterConvertible _LIBCPP_NODEBUG_TYPE__attribute__((nodebug)) = typename enable_if<
167 (is_reference<_Dp>::value && is_same<_Dp, _UDel>::value) ||
168 (!is_reference<_Dp>::value && is_convertible<_UDel, _Dp>::value)
169 >::type;
170
171 template <class _UDel>
172 using _EnableIfDeleterAssignable = typename enable_if<
173 is_assignable<_Dp&, _UDel&&>::value
174 >::type;
175
176public:
177 template <bool _Dummy = true,
178 class = _EnableIfDeleterDefaultConstructible<_Dummy> >
179 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
180 _LIBCPP_CONSTEXPRconstexpr unique_ptr() _NOEXCEPTnoexcept : __ptr_(pointer(), __default_init_tag()) {}
181
182 template <bool _Dummy = true,
183 class = _EnableIfDeleterDefaultConstructible<_Dummy> >
184 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
185 _LIBCPP_CONSTEXPRconstexpr unique_ptr(nullptr_t) _NOEXCEPTnoexcept : __ptr_(pointer(), __default_init_tag()) {}
186
187 template <bool _Dummy = true,
188 class = _EnableIfDeleterDefaultConstructible<_Dummy> >
189 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
190 explicit unique_ptr(pointer __p) _NOEXCEPTnoexcept : __ptr_(__p, __default_init_tag()) {}
191
192 template <bool _Dummy = true,
193 class = _EnableIfDeleterConstructible<_LValRefType<_Dummy> > >
194 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
195 unique_ptr(pointer __p, _LValRefType<_Dummy> __d) _NOEXCEPTnoexcept
196 : __ptr_(__p, __d) {}
197
198 template <bool _Dummy = true,
199 class = _EnableIfDeleterConstructible<_GoodRValRefType<_Dummy> > >
200 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
201 unique_ptr(pointer __p, _GoodRValRefType<_Dummy> __d) _NOEXCEPTnoexcept
202 : __ptr_(__p, _VSTDstd::__1::move(__d)) {
203 static_assert(!is_reference<deleter_type>::value,
204 "rvalue deleter bound to reference");
205 }
206
207 template <bool _Dummy = true,
208 class = _EnableIfDeleterConstructible<_BadRValRefType<_Dummy> > >
209 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
210 unique_ptr(pointer __p, _BadRValRefType<_Dummy> __d) = delete;
211
212 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
213 unique_ptr(unique_ptr&& __u) _NOEXCEPTnoexcept
214 : __ptr_(__u.release(), _VSTDstd::__1::forward<deleter_type>(__u.get_deleter())) {
215 }
216
217 template <class _Up, class _Ep,
218 class = _EnableIfMoveConvertible<unique_ptr<_Up, _Ep>, _Up>,
219 class = _EnableIfDeleterConvertible<_Ep>
220 >
221 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
222 unique_ptr(unique_ptr<_Up, _Ep>&& __u) _NOEXCEPTnoexcept
223 : __ptr_(__u.release(), _VSTDstd::__1::forward<_Ep>(__u.get_deleter())) {}
224
225#if _LIBCPP_STD_VER14 <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR)
226 template <class _Up>
227 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
228 unique_ptr(auto_ptr<_Up>&& __p,
229 typename enable_if<is_convertible<_Up*, _Tp*>::value &&
230 is_same<_Dp, default_delete<_Tp> >::value,
231 __nat>::type = __nat()) _NOEXCEPTnoexcept
232 : __ptr_(__p.release(), __default_init_tag()) {}
233#endif
234
235 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
236 unique_ptr& operator=(unique_ptr&& __u) _NOEXCEPTnoexcept {
237 reset(__u.release());
238 __ptr_.second() = _VSTDstd::__1::forward<deleter_type>(__u.get_deleter());
239 return *this;
240 }
241
242 template <class _Up, class _Ep,
243 class = _EnableIfMoveConvertible<unique_ptr<_Up, _Ep>, _Up>,
244 class = _EnableIfDeleterAssignable<_Ep>
245 >
246 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
247 unique_ptr& operator=(unique_ptr<_Up, _Ep>&& __u) _NOEXCEPTnoexcept {
248 reset(__u.release());
249 __ptr_.second() = _VSTDstd::__1::forward<_Ep>(__u.get_deleter());
250 return *this;
251 }
252
253#if _LIBCPP_STD_VER14 <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR)
254 template <class _Up>
255 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
256 typename enable_if<is_convertible<_Up*, _Tp*>::value &&
257 is_same<_Dp, default_delete<_Tp> >::value,
258 unique_ptr&>::type
259 operator=(auto_ptr<_Up> __p) {
260 reset(__p.release());
261 return *this;
262 }
263#endif
264
265#ifdef _LIBCPP_CXX03_LANG
266 unique_ptr(unique_ptr const&) = delete;
267 unique_ptr& operator=(unique_ptr const&) = delete;
268#endif
269
270
271 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
272 ~unique_ptr() { reset(); }
273
274 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
275 unique_ptr& operator=(nullptr_t) _NOEXCEPTnoexcept {
276 reset();
277 return *this;
278 }
279
280 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
281 typename add_lvalue_reference<_Tp>::type
282 operator*() const {
283 return *__ptr_.first();
284 }
285 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
286 pointer operator->() const _NOEXCEPTnoexcept {
287 return __ptr_.first();
288 }
289 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
290 pointer get() const _NOEXCEPTnoexcept {
291 return __ptr_.first();
292 }
293 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
294 deleter_type& get_deleter() _NOEXCEPTnoexcept {
295 return __ptr_.second();
296 }
297 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
298 const deleter_type& get_deleter() const _NOEXCEPTnoexcept {
299 return __ptr_.second();
300 }
301 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
302 explicit operator bool() const _NOEXCEPTnoexcept {
303 return __ptr_.first() != nullptr;
15
Assuming the condition is true
16
Returning the value 1, which participates in a condition later
304 }
305
306 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
307 pointer release() _NOEXCEPTnoexcept {
308 pointer __t = __ptr_.first();
309 __ptr_.first() = pointer();
310 return __t;
311 }
312
313 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
314 void reset(pointer __p = pointer()) _NOEXCEPTnoexcept {
315 pointer __tmp = __ptr_.first();
316 __ptr_.first() = __p;
317 if (__tmp)
318 __ptr_.second()(__tmp);
319 }
320
321 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
322 void swap(unique_ptr& __u) _NOEXCEPTnoexcept {
323 __ptr_.swap(__u.__ptr_);
324 }
325};
326
327
328template <class _Tp, class _Dp>
329class _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS__attribute__ ((__type_visibility__("default"))) unique_ptr<_Tp[], _Dp> {
330public:
331 typedef _Tp element_type;
332 typedef _Dp deleter_type;
333 typedef typename __pointer<_Tp, deleter_type>::type pointer;
334
335private:
336 __compressed_pair<pointer, deleter_type> __ptr_;
337
338 template <class _From>
339 struct _CheckArrayPointerConversion : is_same<_From, pointer> {};
340
341 template <class _FromElem>
342 struct _CheckArrayPointerConversion<_FromElem*>
343 : integral_constant<bool,
344 is_same<_FromElem*, pointer>::value ||
345 (is_same<pointer, element_type*>::value &&
346 is_convertible<_FromElem(*)[], element_type(*)[]>::value)
347 >
348 {};
349
350 typedef __unique_ptr_deleter_sfinae<_Dp> _DeleterSFINAE;
351
352 template <bool _Dummy>
353 using _LValRefType _LIBCPP_NODEBUG_TYPE__attribute__((nodebug)) =
354 typename __dependent_type<_DeleterSFINAE, _Dummy>::__lval_ref_type;
355
356 template <bool _Dummy>
357 using _GoodRValRefType _LIBCPP_NODEBUG_TYPE__attribute__((nodebug)) =
358 typename __dependent_type<_DeleterSFINAE, _Dummy>::__good_rval_ref_type;
359
360 template <bool _Dummy>
361 using _BadRValRefType _LIBCPP_NODEBUG_TYPE__attribute__((nodebug)) =
362 typename __dependent_type<_DeleterSFINAE, _Dummy>::__bad_rval_ref_type;
363
364 template <bool _Dummy, class _Deleter = typename __dependent_type<
365 __identity<deleter_type>, _Dummy>::type>
366 using _EnableIfDeleterDefaultConstructible _LIBCPP_NODEBUG_TYPE__attribute__((nodebug)) =
367 typename enable_if<is_default_constructible<_Deleter>::value &&
368 !is_pointer<_Deleter>::value>::type;
369
370 template <class _ArgType>
371 using _EnableIfDeleterConstructible _LIBCPP_NODEBUG_TYPE__attribute__((nodebug)) =
372 typename enable_if<is_constructible<deleter_type, _ArgType>::value>::type;
373
374 template <class _Pp>
375 using _EnableIfPointerConvertible _LIBCPP_NODEBUG_TYPE__attribute__((nodebug)) = typename enable_if<
376 _CheckArrayPointerConversion<_Pp>::value
377 >::type;
378
379 template <class _UPtr, class _Up,
380 class _ElemT = typename _UPtr::element_type>
381 using _EnableIfMoveConvertible _LIBCPP_NODEBUG_TYPE__attribute__((nodebug)) = typename enable_if<
382 is_array<_Up>::value &&
383 is_same<pointer, element_type*>::value &&
384 is_same<typename _UPtr::pointer, _ElemT*>::value &&
385 is_convertible<_ElemT(*)[], element_type(*)[]>::value
386 >::type;
387
388 template <class _UDel>
389 using _EnableIfDeleterConvertible _LIBCPP_NODEBUG_TYPE__attribute__((nodebug)) = typename enable_if<
390 (is_reference<_Dp>::value && is_same<_Dp, _UDel>::value) ||
391 (!is_reference<_Dp>::value && is_convertible<_UDel, _Dp>::value)
392 >::type;
393
394 template <class _UDel>
395 using _EnableIfDeleterAssignable _LIBCPP_NODEBUG_TYPE__attribute__((nodebug)) = typename enable_if<
396 is_assignable<_Dp&, _UDel&&>::value
397 >::type;
398
399public:
400 template <bool _Dummy = true,
401 class = _EnableIfDeleterDefaultConstructible<_Dummy> >
402 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
403 _LIBCPP_CONSTEXPRconstexpr unique_ptr() _NOEXCEPTnoexcept : __ptr_(pointer(), __default_init_tag()) {}
404
405 template <bool _Dummy = true,
406 class = _EnableIfDeleterDefaultConstructible<_Dummy> >
407 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
408 _LIBCPP_CONSTEXPRconstexpr unique_ptr(nullptr_t) _NOEXCEPTnoexcept : __ptr_(pointer(), __default_init_tag()) {}
409
410 template <class _Pp, bool _Dummy = true,
411 class = _EnableIfDeleterDefaultConstructible<_Dummy>,
412 class = _EnableIfPointerConvertible<_Pp> >
413 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
414 explicit unique_ptr(_Pp __p) _NOEXCEPTnoexcept
415 : __ptr_(__p, __default_init_tag()) {}
416
417 template <class _Pp, bool _Dummy = true,
418 class = _EnableIfDeleterConstructible<_LValRefType<_Dummy> >,
419 class = _EnableIfPointerConvertible<_Pp> >
420 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
421 unique_ptr(_Pp __p, _LValRefType<_Dummy> __d) _NOEXCEPTnoexcept
422 : __ptr_(__p, __d) {}
423
424 template <bool _Dummy = true,
425 class = _EnableIfDeleterConstructible<_LValRefType<_Dummy> > >
426 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
427 unique_ptr(nullptr_t, _LValRefType<_Dummy> __d) _NOEXCEPTnoexcept
428 : __ptr_(nullptr, __d) {}
429
430 template <class _Pp, bool _Dummy = true,
431 class = _EnableIfDeleterConstructible<_GoodRValRefType<_Dummy> >,
432 class = _EnableIfPointerConvertible<_Pp> >
433 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
434 unique_ptr(_Pp __p, _GoodRValRefType<_Dummy> __d) _NOEXCEPTnoexcept
435 : __ptr_(__p, _VSTDstd::__1::move(__d)) {
436 static_assert(!is_reference<deleter_type>::value,
437 "rvalue deleter bound to reference");
438 }
439
440 template <bool _Dummy = true,
441 class = _EnableIfDeleterConstructible<_GoodRValRefType<_Dummy> > >
442 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
443 unique_ptr(nullptr_t, _GoodRValRefType<_Dummy> __d) _NOEXCEPTnoexcept
444 : __ptr_(nullptr, _VSTDstd::__1::move(__d)) {
445 static_assert(!is_reference<deleter_type>::value,
446 "rvalue deleter bound to reference");
447 }
448
449 template <class _Pp, bool _Dummy = true,
450 class = _EnableIfDeleterConstructible<_BadRValRefType<_Dummy> >,
451 class = _EnableIfPointerConvertible<_Pp> >
452 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
453 unique_ptr(_Pp __p, _BadRValRefType<_Dummy> __d) = delete;
454
455 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
456 unique_ptr(unique_ptr&& __u) _NOEXCEPTnoexcept
457 : __ptr_(__u.release(), _VSTDstd::__1::forward<deleter_type>(__u.get_deleter())) {
458 }
459
460 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
461 unique_ptr& operator=(unique_ptr&& __u) _NOEXCEPTnoexcept {
462 reset(__u.release());
463 __ptr_.second() = _VSTDstd::__1::forward<deleter_type>(__u.get_deleter());
464 return *this;
465 }
466
467 template <class _Up, class _Ep,
468 class = _EnableIfMoveConvertible<unique_ptr<_Up, _Ep>, _Up>,
469 class = _EnableIfDeleterConvertible<_Ep>
470 >
471 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
472 unique_ptr(unique_ptr<_Up, _Ep>&& __u) _NOEXCEPTnoexcept
473 : __ptr_(__u.release(), _VSTDstd::__1::forward<_Ep>(__u.get_deleter())) {
474 }
475
476 template <class _Up, class _Ep,
477 class = _EnableIfMoveConvertible<unique_ptr<_Up, _Ep>, _Up>,
478 class = _EnableIfDeleterAssignable<_Ep>
479 >
480 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
481 unique_ptr&
482 operator=(unique_ptr<_Up, _Ep>&& __u) _NOEXCEPTnoexcept {
483 reset(__u.release());
484 __ptr_.second() = _VSTDstd::__1::forward<_Ep>(__u.get_deleter());
485 return *this;
486 }
487
488#ifdef _LIBCPP_CXX03_LANG
489 unique_ptr(unique_ptr const&) = delete;
490 unique_ptr& operator=(unique_ptr const&) = delete;
491#endif
492
493public:
494 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
495 ~unique_ptr() { reset(); }
496
497 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
498 unique_ptr& operator=(nullptr_t) _NOEXCEPTnoexcept {
499 reset();
500 return *this;
501 }
502
503 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
504 typename add_lvalue_reference<_Tp>::type
505 operator[](size_t __i) const {
506 return __ptr_.first()[__i];
507 }
508 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
509 pointer get() const _NOEXCEPTnoexcept {
510 return __ptr_.first();
511 }
512
513 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
514 deleter_type& get_deleter() _NOEXCEPTnoexcept {
515 return __ptr_.second();
516 }
517
518 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
519 const deleter_type& get_deleter() const _NOEXCEPTnoexcept {
520 return __ptr_.second();
521 }
522 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
523 explicit operator bool() const _NOEXCEPTnoexcept {
524 return __ptr_.first() != nullptr;
525 }
526
527 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
528 pointer release() _NOEXCEPTnoexcept {
529 pointer __t = __ptr_.first();
530 __ptr_.first() = pointer();
531 return __t;
532 }
533
534 template <class _Pp>
535 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
536 typename enable_if<
537 _CheckArrayPointerConversion<_Pp>::value
538 >::type
539 reset(_Pp __p) _NOEXCEPTnoexcept {
540 pointer __tmp = __ptr_.first();
541 __ptr_.first() = __p;
542 if (__tmp)
543 __ptr_.second()(__tmp);
544 }
545
546 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
547 void reset(nullptr_t = nullptr) _NOEXCEPTnoexcept {
548 pointer __tmp = __ptr_.first();
549 __ptr_.first() = nullptr;
550 if (__tmp)
551 __ptr_.second()(__tmp);
552 }
553
554 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
555 void swap(unique_ptr& __u) _NOEXCEPTnoexcept {
556 __ptr_.swap(__u.__ptr_);
557 }
558
559};
560
561template <class _Tp, class _Dp>
562inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
563typename enable_if<
564 __is_swappable<_Dp>::value,
565 void
566>::type
567swap(unique_ptr<_Tp, _Dp>& __x, unique_ptr<_Tp, _Dp>& __y) _NOEXCEPTnoexcept {__x.swap(__y);}
568
569template <class _T1, class _D1, class _T2, class _D2>
570inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
571bool
572operator==(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {return __x.get() == __y.get();}
573
574template <class _T1, class _D1, class _T2, class _D2>
575inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
576bool
577operator!=(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {return !(__x == __y);}
578
579template <class _T1, class _D1, class _T2, class _D2>
580inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
581bool
582operator< (const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y)
583{
584 typedef typename unique_ptr<_T1, _D1>::pointer _P1;
585 typedef typename unique_ptr<_T2, _D2>::pointer _P2;
586 typedef typename common_type<_P1, _P2>::type _Vp;
587 return less<_Vp>()(__x.get(), __y.get());
588}
589
590template <class _T1, class _D1, class _T2, class _D2>
591inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
592bool
593operator> (const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {return __y < __x;}
594
595template <class _T1, class _D1, class _T2, class _D2>
596inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
597bool
598operator<=(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {return !(__y < __x);}
599
600template <class _T1, class _D1, class _T2, class _D2>
601inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
602bool
603operator>=(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {return !(__x < __y);}
604
605template <class _T1, class _D1>
606inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
607bool
608operator==(const unique_ptr<_T1, _D1>& __x, nullptr_t) _NOEXCEPTnoexcept
609{
610 return !__x;
611}
612
613template <class _T1, class _D1>
614inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
615bool
616operator==(nullptr_t, const unique_ptr<_T1, _D1>& __x) _NOEXCEPTnoexcept
617{
618 return !__x;
619}
620
621template <class _T1, class _D1>
622inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
623bool
624operator!=(const unique_ptr<_T1, _D1>& __x, nullptr_t) _NOEXCEPTnoexcept
625{
626 return static_cast<bool>(__x);
627}
628
629template <class _T1, class _D1>
630inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
631bool
632operator!=(nullptr_t, const unique_ptr<_T1, _D1>& __x) _NOEXCEPTnoexcept
633{
634 return static_cast<bool>(__x);
635}
636
637template <class _T1, class _D1>
638inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
639bool
640operator<(const unique_ptr<_T1, _D1>& __x, nullptr_t)
641{
642 typedef typename unique_ptr<_T1, _D1>::pointer _P1;
643 return less<_P1>()(__x.get(), nullptr);
644}
645
646template <class _T1, class _D1>
647inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
648bool
649operator<(nullptr_t, const unique_ptr<_T1, _D1>& __x)
650{
651 typedef typename unique_ptr<_T1, _D1>::pointer _P1;
652 return less<_P1>()(nullptr, __x.get());
653}
654
655template <class _T1, class _D1>
656inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
657bool
658operator>(const unique_ptr<_T1, _D1>& __x, nullptr_t)
659{
660 return nullptr < __x;
661}
662
663template <class _T1, class _D1>
664inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
665bool
666operator>(nullptr_t, const unique_ptr<_T1, _D1>& __x)
667{
668 return __x < nullptr;
669}
670
671template <class _T1, class _D1>
672inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
673bool
674operator<=(const unique_ptr<_T1, _D1>& __x, nullptr_t)
675{
676 return !(nullptr < __x);
677}
678
679template <class _T1, class _D1>
680inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
681bool
682operator<=(nullptr_t, const unique_ptr<_T1, _D1>& __x)
683{
684 return !(__x < nullptr);
685}
686
687template <class _T1, class _D1>
688inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
689bool
690operator>=(const unique_ptr<_T1, _D1>& __x, nullptr_t)
691{
692 return !(__x < nullptr);
693}
694
695template <class _T1, class _D1>
696inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
697bool
698operator>=(nullptr_t, const unique_ptr<_T1, _D1>& __x)
699{
700 return !(nullptr < __x);
701}
702
703#if _LIBCPP_STD_VER14 > 11
704
705template<class _Tp>
706struct __unique_if
707{
708 typedef unique_ptr<_Tp> __unique_single;
709};
710
711template<class _Tp>
712struct __unique_if<_Tp[]>
713{
714 typedef unique_ptr<_Tp[]> __unique_array_unknown_bound;
715};
716
717template<class _Tp, size_t _Np>
718struct __unique_if<_Tp[_Np]>
719{
720 typedef void __unique_array_known_bound;
721};
722
723template<class _Tp, class... _Args>
724inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
725typename __unique_if<_Tp>::__unique_single
726make_unique(_Args&&... __args)
727{
728 return unique_ptr<_Tp>(new _Tp(_VSTDstd::__1::forward<_Args>(__args)...));
729}
730
731template<class _Tp>
732inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
733typename __unique_if<_Tp>::__unique_array_unknown_bound
734make_unique(size_t __n)
735{
736 typedef typename remove_extent<_Tp>::type _Up;
737 return unique_ptr<_Tp>(new _Up[__n]());
738}
739
740template<class _Tp, class... _Args>
741 typename __unique_if<_Tp>::__unique_array_known_bound
742 make_unique(_Args&&...) = delete;
743
744#endif // _LIBCPP_STD_VER > 11
745
746template <class _Tp> struct _LIBCPP_TEMPLATE_VIS__attribute__ ((__type_visibility__("default"))) hash;
747
748template <class _Tp, class _Dp>
749#ifdef _LIBCPP_CXX03_LANG
750struct _LIBCPP_TEMPLATE_VIS__attribute__ ((__type_visibility__("default"))) hash<unique_ptr<_Tp, _Dp> >
751#else
752struct _LIBCPP_TEMPLATE_VIS__attribute__ ((__type_visibility__("default"))) hash<__enable_hash_helper<
753 unique_ptr<_Tp, _Dp>, typename unique_ptr<_Tp, _Dp>::pointer> >
754#endif
755{
756#if _LIBCPP_STD_VER14 <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
757 _LIBCPP_DEPRECATED_IN_CXX17 typedef unique_ptr<_Tp, _Dp> argument_type;
758 _LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type;
759#endif
760
761 _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__
))
762 size_t operator()(const unique_ptr<_Tp, _Dp>& __ptr) const
763 {
764 typedef typename unique_ptr<_Tp, _Dp>::pointer pointer;
765 return hash<pointer>()(__ptr.get());
766 }
767};
768
769_LIBCPP_END_NAMESPACE_STD} }
770
771_LIBCPP_POP_MACROSpop_macro("min") pop_macro("max")
772
773#endif // _LIBCPP___MEMORY_UNIQUE_PTR_H