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 |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
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 | ||||
55 | using namespace lldb; | |||
56 | using namespace lldb_private; | |||
57 | using namespace llvm::pdb; | |||
58 | ||||
59 | LLDB_PLUGIN_DEFINE(SymbolFilePDB)namespace lldb_private { void lldb_initialize_SymbolFilePDB() { SymbolFilePDB::Initialize(); } void lldb_terminate_SymbolFilePDB () { SymbolFilePDB::Terminate(); } } | |||
60 | ||||
61 | char SymbolFilePDB::ID; | |||
62 | ||||
63 | namespace { | |||
64 | lldb::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 | ||||
77 | bool 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 | ||||
84 | static 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 | ||||
96 | void SymbolFilePDB::Initialize() { | |||
97 | if (ShouldUseNativeReader()) { | |||
98 | npdb::SymbolFileNativePDB::Initialize(); | |||
99 | } else { | |||
100 | PluginManager::RegisterPlugin(GetPluginNameStatic(), | |||
101 | GetPluginDescriptionStatic(), CreateInstance, | |||
102 | DebuggerInitialize); | |||
103 | } | |||
104 | } | |||
105 | ||||
106 | void SymbolFilePDB::Terminate() { | |||
107 | if (ShouldUseNativeReader()) { | |||
108 | npdb::SymbolFileNativePDB::Terminate(); | |||
109 | } else { | |||
110 | PluginManager::UnregisterPlugin(CreateInstance); | |||
111 | } | |||
112 | } | |||
113 | ||||
114 | void SymbolFilePDB::DebuggerInitialize(lldb_private::Debugger &debugger) {} | |||
115 | ||||
116 | lldb_private::ConstString SymbolFilePDB::GetPluginNameStatic() { | |||
117 | static ConstString g_name("pdb"); | |||
118 | return g_name; | |||
119 | } | |||
120 | ||||
121 | const char *SymbolFilePDB::GetPluginDescriptionStatic() { | |||
122 | return "Microsoft PDB debug symbol file reader."; | |||
123 | } | |||
124 | ||||
125 | lldb_private::SymbolFile * | |||
126 | SymbolFilePDB::CreateInstance(ObjectFileSP objfile_sp) { | |||
127 | return new SymbolFilePDB(std::move(objfile_sp)); | |||
128 | } | |||
129 | ||||
130 | SymbolFilePDB::SymbolFilePDB(lldb::ObjectFileSP objfile_sp) | |||
131 | : SymbolFile(std::move(objfile_sp)), m_session_up(), m_global_scope_up() {} | |||
132 | ||||
133 | SymbolFilePDB::~SymbolFilePDB() = default; | |||
134 | ||||
135 | uint32_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 | ||||
189 | void 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 | ||||
199 | uint32_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 | ||||
225 | void 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 | ||||
244 | std::unique_ptr<llvm::pdb::PDBSymbolCompiland> | |||
245 | SymbolFilePDB::GetPDBCompilandByUID(uint32_t uid) { | |||
246 | return m_session_up->getConcreteSymbolById<PDBSymbolCompiland>(uid); | |||
247 | } | |||
248 | ||||
249 | lldb::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 | ||||
265 | lldb::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 | ||||
276 | lldb_private::Function * | |||
277 | SymbolFilePDB::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 | ||||
324 | size_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 | ||||
343 | bool 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 | ||||
350 | bool SymbolFilePDB::ParseDebugMacros(CompileUnit &comp_unit) { | |||
351 | // PDB doesn't contain information about macros | |||
352 | return false; | |||
353 | } | |||
354 | ||||
355 | bool 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 | ||||
379 | bool 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 | ||||
386 | static 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 | ||||
436 | size_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 | ||||
449 | size_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 | ||||
501 | size_t | |||
502 | SymbolFilePDB::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 | ||||
551 | lldb_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 | ||||
585 | llvm::Optional<SymbolFile::ArrayInfo> SymbolFilePDB::GetDynamicArrayInfoForUID( | |||
586 | lldb::user_id_t type_uid, const lldb_private::ExecutionContext *exe_ctx) { | |||
587 | return llvm::None; | |||
588 | } | |||
589 | ||||
590 | bool 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 | ||||
615 | lldb_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 | ||||
644 | lldb_private::CompilerDeclContext | |||
645 | SymbolFilePDB::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 | ||||
674 | lldb_private::CompilerDeclContext | |||
675 | SymbolFilePDB::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 | ||||
703 | void 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 | ||||
726 | uint32_t | |||
727 | SymbolFilePDB::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 || | |||
| ||||
733 | resolve_scope & eSymbolContextVariable || | |||
734 | resolve_scope & eSymbolContextFunction || | |||
735 | resolve_scope & eSymbolContextBlock || | |||
736 | resolve_scope & eSymbolContextLineEntry) { | |||
737 | auto cu_sp = GetCompileUnitContainsAddress(so_addr); | |||
738 | if (!cu_sp) { | |||
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 || | |||
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) { | |||
755 | auto *pdb_func = llvm::dyn_cast<PDBSymbolFunc>(symbol_up.get()); | |||
756 | assert(pdb_func)((void)0); | |||
757 | auto func_uid = pdb_func->getSymIndexId(); | |||
| ||||
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 | ||||
788 | uint32_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 | ||||
902 | std::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 | ||||
915 | VariableSP 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 | ||||
1032 | size_t | |||
1033 | SymbolFilePDB::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 | ||||
1102 | void 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 | ||||
1144 | void SymbolFilePDB::FindGlobalVariables( | |||
1145 | const lldb_private::RegularExpression ®ex, 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 | ||||
1179 | bool 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 | ||||
1195 | bool 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 | ||||
1203 | void 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 | ||||
1298 | void 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 | ||||
1349 | void SymbolFilePDB::FindFunctions(const lldb_private::RegularExpression ®ex, | |||
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 = [®ex, 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 | ||||
1374 | void SymbolFilePDB::GetMangledNamesForFunction( | |||
1375 | const std::string &scope_qualified_name, | |||
1376 | std::vector<lldb_private::ConstString> &mangled_names) {} | |||
1377 | ||||
1378 | void 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 | ||||
1427 | void 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 | ||||
1445 | void 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 | ||||
1461 | void SymbolFilePDB::FindTypesByRegex( | |||
1462 | const lldb_private::RegularExpression ®ex, 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 | ||||
1516 | void 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 | ||||
1565 | void SymbolFilePDB::FindTypes( | |||
1566 | llvm::ArrayRef<CompilerContext> pattern, LanguageSet languages, | |||
1567 | llvm::DenseSet<SymbolFile *> &searched_symbol_files, | |||
1568 | lldb_private::TypeMap &types) {} | |||
1569 | ||||
1570 | void 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 | ||||
1620 | void 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 | ||||
1648 | llvm::Expected<lldb_private::TypeSystem &> | |||
1649 | SymbolFilePDB::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 | ||||
1658 | PDBASTParser *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 | ||||
1675 | lldb_private::CompilerDeclContext | |||
1676 | SymbolFilePDB::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 | ||||
1710 | lldb_private::ConstString SymbolFilePDB::GetPluginName() { | |||
1711 | static ConstString g_name("pdb"); | |||
1712 | return g_name; | |||
1713 | } | |||
1714 | ||||
1715 | uint32_t SymbolFilePDB::GetPluginVersion() { return 1; } | |||
1716 | ||||
1717 | IPDBSession &SymbolFilePDB::GetPDBSession() { return *m_session_up; } | |||
1718 | ||||
1719 | const IPDBSession &SymbolFilePDB::GetPDBSession() const { | |||
1720 | return *m_session_up; | |||
1721 | } | |||
1722 | ||||
1723 | lldb::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 | ||||
1764 | bool 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 | ||||
1868 | void 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 | ||||
1887 | lldb::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 | ||||
1911 | Mangled | |||
1912 | SymbolFilePDB::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 | ||||
1973 | bool 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 | ||||
1997 | uint32_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 | } |
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 | |
51 | template <class _Alloc> |
52 | class __allocator_destructor |
53 | { |
54 | typedef _LIBCPP_NODEBUG_TYPE__attribute__((nodebug)) allocator_traits<_Alloc> __alloc_traits; |
55 | public: |
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; |
58 | private: |
59 | _Alloc& __alloc_; |
60 | size_type __s_; |
61 | public: |
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 | |
81 | template <class _ValueType> |
82 | inline _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 | |
93 | template <class _ValueType> |
94 | inline _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 | |
105 | template <class _Tp> |
106 | inline _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 | |
116 | template <class _Tp> |
117 | inline _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 | |
127 | class _LIBCPP_EXCEPTION_ABI__attribute__ ((__visibility__("default"))) bad_weak_ptr |
128 | : public std::exception |
129 | { |
130 | public: |
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__ )) |
138 | void __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 | |
147 | template<class _Tp> class _LIBCPP_TEMPLATE_VIS__attribute__ ((__type_visibility__("default"))) weak_ptr; |
148 | |
149 | class _LIBCPP_TYPE_VIS__attribute__ ((__visibility__("default"))) __shared_count |
150 | { |
151 | __shared_count(const __shared_count&); |
152 | __shared_count& operator=(const __shared_count&); |
153 | |
154 | protected: |
155 | long __shared_owners_; |
156 | virtual ~__shared_count(); |
157 | private: |
158 | virtual void __on_zero_shared() _NOEXCEPTnoexcept = 0; |
159 | |
160 | public: |
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 | |
189 | class _LIBCPP_TYPE_VIS__attribute__ ((__visibility__("default"))) __shared_weak_count |
190 | : private __shared_count |
191 | { |
192 | long __shared_weak_owners_; |
193 | |
194 | public: |
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) {} |
199 | protected: |
200 | virtual ~__shared_weak_count(); |
201 | |
202 | public: |
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; |
229 | private: |
230 | virtual void __on_zero_shared_weak() _NOEXCEPTnoexcept = 0; |
231 | }; |
232 | |
233 | template <class _Tp, class _Dp, class _Alloc> |
234 | class __shared_ptr_pointer |
235 | : public __shared_weak_count |
236 | { |
237 | __compressed_pair<__compressed_pair<_Tp, _Dp>, _Alloc> __data_; |
238 | public: |
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 | |
247 | private: |
248 | virtual void __on_zero_shared() _NOEXCEPTnoexcept; |
249 | virtual void __on_zero_shared_weak() _NOEXCEPTnoexcept; |
250 | }; |
251 | |
252 | #ifndef _LIBCPP_NO_RTTI |
253 | |
254 | template <class _Tp, class _Dp, class _Alloc> |
255 | const 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 | |
263 | template <class _Tp, class _Dp, class _Alloc> |
264 | void |
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 | |
271 | template <class _Tp, class _Dp, class _Alloc> |
272 | void |
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 | |
284 | template <class _Tp, class _Alloc> |
285 | struct __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 | |
308 | private: |
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 | |
365 | struct __shared_ptr_dummy_rebind_allocator_type; |
366 | template <> |
367 | class _LIBCPP_TEMPLATE_VIS__attribute__ ((__type_visibility__("default"))) allocator<__shared_ptr_dummy_rebind_allocator_type> |
368 | { |
369 | public: |
370 | template <class _Other> |
371 | struct rebind |
372 | { |
373 | typedef allocator<_Other> other; |
374 | }; |
375 | }; |
376 | |
377 | template<class _Tp> class _LIBCPP_TEMPLATE_VIS__attribute__ ((__type_visibility__("default"))) enable_shared_from_this; |
378 | |
379 | template<class _Tp, class _Up> |
380 | struct __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 | |
387 | template <class _Ptr, class = void> |
388 | struct __is_deletable : false_type { }; |
389 | template <class _Ptr> |
390 | struct __is_deletable<_Ptr, decltype(delete declval<_Ptr>())> : true_type { }; |
391 | |
392 | template <class _Ptr, class = void> |
393 | struct __is_array_deletable : false_type { }; |
394 | template <class _Ptr> |
395 | struct __is_array_deletable<_Ptr, decltype(delete[] declval<_Ptr>())> : true_type { }; |
396 | |
397 | template <class _Dp, class _Pt, |
398 | class = decltype(declval<_Dp>()(declval<_Pt>()))> |
399 | static true_type __well_formed_deleter_test(int); |
400 | |
401 | template <class, class> |
402 | static false_type __well_formed_deleter_test(...); |
403 | |
404 | template <class _Dp, class _Pt> |
405 | struct __well_formed_deleter : decltype(__well_formed_deleter_test<_Dp, _Pt>(0)) {}; |
406 | |
407 | template<class _Dp, class _Tp, class _Yp> |
408 | struct __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 | |
421 | template<class _Tp> |
422 | class _LIBCPP_SHARED_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS__attribute__ ((__type_visibility__("default"))) shared_ptr |
423 | { |
424 | public: |
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 | |
432 | private: |
433 | element_type* __ptr_; |
434 | __shared_weak_count* __cntrl_; |
435 | |
436 | struct __nat {int __for_bool_;}; |
437 | public: |
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;} |
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 | |
641 | private: |
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 |
690 | template<class _Tp> |
691 | shared_ptr(weak_ptr<_Tp>) -> shared_ptr<_Tp>; |
692 | template<class _Tp, class _Dp> |
693 | shared_ptr(unique_ptr<_Tp, _Dp>) -> shared_ptr<_Tp>; |
694 | #endif |
695 | |
696 | template<class _Tp> |
697 | inline |
698 | _LIBCPP_CONSTEXPRconstexpr |
699 | shared_ptr<_Tp>::shared_ptr() _NOEXCEPTnoexcept |
700 | : __ptr_(nullptr), |
701 | __cntrl_(nullptr) |
702 | { |
703 | } |
704 | |
705 | template<class _Tp> |
706 | inline |
707 | _LIBCPP_CONSTEXPRconstexpr |
708 | shared_ptr<_Tp>::shared_ptr(nullptr_t) _NOEXCEPTnoexcept |
709 | : __ptr_(nullptr), |
710 | __cntrl_(nullptr) |
711 | { |
712 | } |
713 | |
714 | template<class _Tp> |
715 | template<class _Yp, class _Dp> |
716 | shared_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 | |
742 | template<class _Tp> |
743 | template<class _Dp> |
744 | shared_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 | |
768 | template<class _Tp> |
769 | template<class _Yp, class _Dp, class _Alloc> |
770 | shared_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 | |
801 | template<class _Tp> |
802 | template<class _Dp, class _Alloc> |
803 | shared_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 | |
832 | template<class _Tp> |
833 | template<class _Yp> |
834 | inline |
835 | shared_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 | |
843 | template<class _Tp> |
844 | inline |
845 | shared_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 | |
853 | template<class _Tp> |
854 | template<class _Yp> |
855 | inline |
856 | shared_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 | |
866 | template<class _Tp> |
867 | inline |
868 | shared_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 | |
876 | template<class _Tp> |
877 | template<class _Yp> |
878 | inline |
879 | shared_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) |
890 | template<class _Tp> |
891 | template<class _Yp> |
892 | shared_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 | |
903 | template<class _Tp> |
904 | template <class _Yp, class _Dp> |
905 | shared_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 | |
928 | template<class _Tp> |
929 | template <class _Yp, class _Dp> |
930 | shared_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 | |
955 | template<class _Tp> |
956 | shared_ptr<_Tp>::~shared_ptr() |
957 | { |
958 | if (__cntrl_) |
959 | __cntrl_->__release_shared(); |
960 | } |
961 | |
962 | template<class _Tp> |
963 | inline |
964 | shared_ptr<_Tp>& |
965 | shared_ptr<_Tp>::operator=(const shared_ptr& __r) _NOEXCEPTnoexcept |
966 | { |
967 | shared_ptr(__r).swap(*this); |
968 | return *this; |
969 | } |
970 | |
971 | template<class _Tp> |
972 | template<class _Yp> |
973 | inline |
974 | typename enable_if |
975 | < |
976 | __compatible_with<_Yp, typename shared_ptr<_Tp>::element_type>::value, |
977 | shared_ptr<_Tp>& |
978 | >::type |
979 | shared_ptr<_Tp>::operator=(const shared_ptr<_Yp>& __r) _NOEXCEPTnoexcept |
980 | { |
981 | shared_ptr(__r).swap(*this); |
982 | return *this; |
983 | } |
984 | |
985 | template<class _Tp> |
986 | inline |
987 | shared_ptr<_Tp>& |
988 | shared_ptr<_Tp>::operator=(shared_ptr&& __r) _NOEXCEPTnoexcept |
989 | { |
990 | shared_ptr(_VSTDstd::__1::move(__r)).swap(*this); |
991 | return *this; |
992 | } |
993 | |
994 | template<class _Tp> |
995 | template<class _Yp> |
996 | inline |
997 | typename enable_if |
998 | < |
999 | __compatible_with<_Yp, typename shared_ptr<_Tp>::element_type>::value, |
1000 | shared_ptr<_Tp>& |
1001 | >::type |
1002 | shared_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) |
1009 | template<class _Tp> |
1010 | template<class _Yp> |
1011 | inline |
1012 | typename 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& |
1018 | shared_ptr<_Tp>::operator=(auto_ptr<_Yp>&& __r) |
1019 | { |
1020 | shared_ptr(_VSTDstd::__1::move(__r)).swap(*this); |
1021 | return *this; |
1022 | } |
1023 | #endif |
1024 | |
1025 | template<class _Tp> |
1026 | template <class _Yp, class _Dp> |
1027 | inline |
1028 | typename 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 |
1034 | shared_ptr<_Tp>::operator=(unique_ptr<_Yp, _Dp>&& __r) |
1035 | { |
1036 | shared_ptr(_VSTDstd::__1::move(__r)).swap(*this); |
1037 | return *this; |
1038 | } |
1039 | |
1040 | template<class _Tp> |
1041 | inline |
1042 | void |
1043 | shared_ptr<_Tp>::swap(shared_ptr& __r) _NOEXCEPTnoexcept |
1044 | { |
1045 | _VSTDstd::__1::swap(__ptr_, __r.__ptr_); |
1046 | _VSTDstd::__1::swap(__cntrl_, __r.__cntrl_); |
1047 | } |
1048 | |
1049 | template<class _Tp> |
1050 | inline |
1051 | void |
1052 | shared_ptr<_Tp>::reset() _NOEXCEPTnoexcept |
1053 | { |
1054 | shared_ptr().swap(*this); |
1055 | } |
1056 | |
1057 | template<class _Tp> |
1058 | template<class _Yp> |
1059 | inline |
1060 | typename enable_if |
1061 | < |
1062 | __compatible_with<_Yp, typename shared_ptr<_Tp>::element_type>::value, |
1063 | void |
1064 | >::type |
1065 | shared_ptr<_Tp>::reset(_Yp* __p) |
1066 | { |
1067 | shared_ptr(__p).swap(*this); |
1068 | } |
1069 | |
1070 | template<class _Tp> |
1071 | template<class _Yp, class _Dp> |
1072 | inline |
1073 | typename enable_if |
1074 | < |
1075 | __compatible_with<_Yp, typename shared_ptr<_Tp>::element_type>::value, |
1076 | void |
1077 | >::type |
1078 | shared_ptr<_Tp>::reset(_Yp* __p, _Dp __d) |
1079 | { |
1080 | shared_ptr(__p, __d).swap(*this); |
1081 | } |
1082 | |
1083 | template<class _Tp> |
1084 | template<class _Yp, class _Dp, class _Alloc> |
1085 | inline |
1086 | typename enable_if |
1087 | < |
1088 | __compatible_with<_Yp, typename shared_ptr<_Tp>::element_type>::value, |
1089 | void |
1090 | >::type |
1091 | shared_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 | // |
1099 | template<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__ )) |
1101 | shared_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 | |
1111 | template<class _Tp, class ..._Args, class = _EnableIf<!is_array<_Tp>::value> > |
1112 | _LIBCPP_HIDE_FROM_ABI__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
1113 | shared_ptr<_Tp> make_shared(_Args&& ...__args) |
1114 | { |
1115 | return _VSTDstd::__1::allocate_shared<_Tp>(allocator<_Tp>(), _VSTDstd::__1::forward<_Args>(__args)...); |
1116 | } |
1117 | |
1118 | template<class _Tp, class _Up> |
1119 | inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
1120 | bool |
1121 | operator==(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPTnoexcept |
1122 | { |
1123 | return __x.get() == __y.get(); |
1124 | } |
1125 | |
1126 | template<class _Tp, class _Up> |
1127 | inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
1128 | bool |
1129 | operator!=(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPTnoexcept |
1130 | { |
1131 | return !(__x == __y); |
1132 | } |
1133 | |
1134 | template<class _Tp, class _Up> |
1135 | inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
1136 | bool |
1137 | operator<(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 | |
1148 | template<class _Tp, class _Up> |
1149 | inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
1150 | bool |
1151 | operator>(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPTnoexcept |
1152 | { |
1153 | return __y < __x; |
1154 | } |
1155 | |
1156 | template<class _Tp, class _Up> |
1157 | inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
1158 | bool |
1159 | operator<=(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPTnoexcept |
1160 | { |
1161 | return !(__y < __x); |
1162 | } |
1163 | |
1164 | template<class _Tp, class _Up> |
1165 | inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
1166 | bool |
1167 | operator>=(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPTnoexcept |
1168 | { |
1169 | return !(__x < __y); |
1170 | } |
1171 | |
1172 | template<class _Tp> |
1173 | inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
1174 | bool |
1175 | operator==(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPTnoexcept |
1176 | { |
1177 | return !__x; |
1178 | } |
1179 | |
1180 | template<class _Tp> |
1181 | inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
1182 | bool |
1183 | operator==(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPTnoexcept |
1184 | { |
1185 | return !__x; |
1186 | } |
1187 | |
1188 | template<class _Tp> |
1189 | inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
1190 | bool |
1191 | operator!=(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPTnoexcept |
1192 | { |
1193 | return static_cast<bool>(__x); |
1194 | } |
1195 | |
1196 | template<class _Tp> |
1197 | inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
1198 | bool |
1199 | operator!=(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPTnoexcept |
1200 | { |
1201 | return static_cast<bool>(__x); |
1202 | } |
1203 | |
1204 | template<class _Tp> |
1205 | inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
1206 | bool |
1207 | operator<(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPTnoexcept |
1208 | { |
1209 | return less<_Tp*>()(__x.get(), nullptr); |
1210 | } |
1211 | |
1212 | template<class _Tp> |
1213 | inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
1214 | bool |
1215 | operator<(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPTnoexcept |
1216 | { |
1217 | return less<_Tp*>()(nullptr, __x.get()); |
1218 | } |
1219 | |
1220 | template<class _Tp> |
1221 | inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
1222 | bool |
1223 | operator>(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPTnoexcept |
1224 | { |
1225 | return nullptr < __x; |
1226 | } |
1227 | |
1228 | template<class _Tp> |
1229 | inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
1230 | bool |
1231 | operator>(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPTnoexcept |
1232 | { |
1233 | return __x < nullptr; |
1234 | } |
1235 | |
1236 | template<class _Tp> |
1237 | inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
1238 | bool |
1239 | operator<=(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPTnoexcept |
1240 | { |
1241 | return !(nullptr < __x); |
1242 | } |
1243 | |
1244 | template<class _Tp> |
1245 | inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
1246 | bool |
1247 | operator<=(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPTnoexcept |
1248 | { |
1249 | return !(__x < nullptr); |
1250 | } |
1251 | |
1252 | template<class _Tp> |
1253 | inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
1254 | bool |
1255 | operator>=(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPTnoexcept |
1256 | { |
1257 | return !(__x < nullptr); |
1258 | } |
1259 | |
1260 | template<class _Tp> |
1261 | inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
1262 | bool |
1263 | operator>=(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPTnoexcept |
1264 | { |
1265 | return !(nullptr < __x); |
1266 | } |
1267 | |
1268 | template<class _Tp> |
1269 | inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
1270 | void |
1271 | swap(shared_ptr<_Tp>& __x, shared_ptr<_Tp>& __y) _NOEXCEPTnoexcept |
1272 | { |
1273 | __x.swap(__y); |
1274 | } |
1275 | |
1276 | template<class _Tp, class _Up> |
1277 | inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
1278 | shared_ptr<_Tp> |
1279 | static_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 | |
1286 | template<class _Tp, class _Up> |
1287 | inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
1288 | shared_ptr<_Tp> |
1289 | dynamic_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 | |
1296 | template<class _Tp, class _Up> |
1297 | shared_ptr<_Tp> |
1298 | const_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 | |
1304 | template<class _Tp, class _Up> |
1305 | shared_ptr<_Tp> |
1306 | reinterpret_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 | |
1315 | template<class _Dp, class _Tp> |
1316 | inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
1317 | _Dp* |
1318 | get_deleter(const shared_ptr<_Tp>& __p) _NOEXCEPTnoexcept |
1319 | { |
1320 | return __p.template __get_deleter<_Dp>(); |
1321 | } |
1322 | |
1323 | #endif // _LIBCPP_NO_RTTI |
1324 | |
1325 | template<class _Tp> |
1326 | class _LIBCPP_SHARED_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS__attribute__ ((__type_visibility__("default"))) weak_ptr |
1327 | { |
1328 | public: |
1329 | typedef _Tp element_type; |
1330 | private: |
1331 | element_type* __ptr_; |
1332 | __shared_weak_count* __cntrl_; |
1333 | |
1334 | public: |
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 |
1410 | template<class _Tp> |
1411 | weak_ptr(shared_ptr<_Tp>) -> weak_ptr<_Tp>; |
1412 | #endif |
1413 | |
1414 | template<class _Tp> |
1415 | inline |
1416 | _LIBCPP_CONSTEXPRconstexpr |
1417 | weak_ptr<_Tp>::weak_ptr() _NOEXCEPTnoexcept |
1418 | : __ptr_(nullptr), |
1419 | __cntrl_(nullptr) |
1420 | { |
1421 | } |
1422 | |
1423 | template<class _Tp> |
1424 | inline |
1425 | weak_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 | |
1433 | template<class _Tp> |
1434 | template<class _Yp> |
1435 | inline |
1436 | weak_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 | |
1446 | template<class _Tp> |
1447 | template<class _Yp> |
1448 | inline |
1449 | weak_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 | |
1459 | template<class _Tp> |
1460 | inline |
1461 | weak_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 | |
1469 | template<class _Tp> |
1470 | template<class _Yp> |
1471 | inline |
1472 | weak_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 | |
1482 | template<class _Tp> |
1483 | weak_ptr<_Tp>::~weak_ptr() |
1484 | { |
1485 | if (__cntrl_) |
1486 | __cntrl_->__release_weak(); |
1487 | } |
1488 | |
1489 | template<class _Tp> |
1490 | inline |
1491 | weak_ptr<_Tp>& |
1492 | weak_ptr<_Tp>::operator=(weak_ptr const& __r) _NOEXCEPTnoexcept |
1493 | { |
1494 | weak_ptr(__r).swap(*this); |
1495 | return *this; |
1496 | } |
1497 | |
1498 | template<class _Tp> |
1499 | template<class _Yp> |
1500 | inline |
1501 | typename enable_if |
1502 | < |
1503 | is_convertible<_Yp*, _Tp*>::value, |
1504 | weak_ptr<_Tp>& |
1505 | >::type |
1506 | weak_ptr<_Tp>::operator=(weak_ptr<_Yp> const& __r) _NOEXCEPTnoexcept |
1507 | { |
1508 | weak_ptr(__r).swap(*this); |
1509 | return *this; |
1510 | } |
1511 | |
1512 | template<class _Tp> |
1513 | inline |
1514 | weak_ptr<_Tp>& |
1515 | weak_ptr<_Tp>::operator=(weak_ptr&& __r) _NOEXCEPTnoexcept |
1516 | { |
1517 | weak_ptr(_VSTDstd::__1::move(__r)).swap(*this); |
1518 | return *this; |
1519 | } |
1520 | |
1521 | template<class _Tp> |
1522 | template<class _Yp> |
1523 | inline |
1524 | typename enable_if |
1525 | < |
1526 | is_convertible<_Yp*, _Tp*>::value, |
1527 | weak_ptr<_Tp>& |
1528 | >::type |
1529 | weak_ptr<_Tp>::operator=(weak_ptr<_Yp>&& __r) _NOEXCEPTnoexcept |
1530 | { |
1531 | weak_ptr(_VSTDstd::__1::move(__r)).swap(*this); |
1532 | return *this; |
1533 | } |
1534 | |
1535 | template<class _Tp> |
1536 | template<class _Yp> |
1537 | inline |
1538 | typename enable_if |
1539 | < |
1540 | is_convertible<_Yp*, _Tp*>::value, |
1541 | weak_ptr<_Tp>& |
1542 | >::type |
1543 | weak_ptr<_Tp>::operator=(shared_ptr<_Yp> const& __r) _NOEXCEPTnoexcept |
1544 | { |
1545 | weak_ptr(__r).swap(*this); |
1546 | return *this; |
1547 | } |
1548 | |
1549 | template<class _Tp> |
1550 | inline |
1551 | void |
1552 | weak_ptr<_Tp>::swap(weak_ptr& __r) _NOEXCEPTnoexcept |
1553 | { |
1554 | _VSTDstd::__1::swap(__ptr_, __r.__ptr_); |
1555 | _VSTDstd::__1::swap(__cntrl_, __r.__cntrl_); |
1556 | } |
1557 | |
1558 | template<class _Tp> |
1559 | inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
1560 | void |
1561 | swap(weak_ptr<_Tp>& __x, weak_ptr<_Tp>& __y) _NOEXCEPTnoexcept |
1562 | { |
1563 | __x.swap(__y); |
1564 | } |
1565 | |
1566 | template<class _Tp> |
1567 | inline |
1568 | void |
1569 | weak_ptr<_Tp>::reset() _NOEXCEPTnoexcept |
1570 | { |
1571 | weak_ptr().swap(*this); |
1572 | } |
1573 | |
1574 | template<class _Tp> |
1575 | template<class _Yp> |
1576 | shared_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 | |
1585 | template<class _Tp> |
1586 | shared_ptr<_Tp> |
1587 | weak_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 |
1597 | template <class _Tp = void> struct owner_less; |
1598 | #else |
1599 | template <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" |
1604 | template <class _Tp> |
1605 | struct _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" |
1628 | template <class _Tp> |
1629 | struct _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 |
1652 | template <> |
1653 | struct _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 | |
1675 | template<class _Tp> |
1676 | class _LIBCPP_TEMPLATE_VIS__attribute__ ((__type_visibility__("default"))) enable_shared_from_this |
1677 | { |
1678 | mutable weak_ptr<_Tp> __weak_this_; |
1679 | protected: |
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() {} |
1689 | public: |
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 | |
1710 | template <class _Tp> struct _LIBCPP_TEMPLATE_VIS__attribute__ ((__type_visibility__("default"))) hash; |
1711 | |
1712 | template <class _Tp> |
1713 | struct _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 | |
1727 | template<class _CharT, class _Traits, class _Yp> |
1728 | inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
1729 | basic_ostream<_CharT, _Traits>& |
1730 | operator<<(basic_ostream<_CharT, _Traits>& __os, shared_ptr<_Yp> const& __p); |
1731 | |
1732 | |
1733 | #if !defined(_LIBCPP_HAS_NO_ATOMIC_HEADER) |
1734 | |
1735 | class _LIBCPP_TYPE_VIS__attribute__ ((__visibility__("default"))) __sp_mut |
1736 | { |
1737 | void* __lx; |
1738 | public: |
1739 | void lock() _NOEXCEPTnoexcept; |
1740 | void unlock() _NOEXCEPTnoexcept; |
1741 | |
1742 | private: |
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 | |
1753 | template <class _Tp> |
1754 | inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
1755 | bool |
1756 | atomic_is_lock_free(const shared_ptr<_Tp>*) |
1757 | { |
1758 | return false; |
1759 | } |
1760 | |
1761 | template <class _Tp> |
1762 | _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR |
1763 | shared_ptr<_Tp> |
1764 | atomic_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 | |
1773 | template <class _Tp> |
1774 | inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
1775 | _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR |
1776 | shared_ptr<_Tp> |
1777 | atomic_load_explicit(const shared_ptr<_Tp>* __p, memory_order) |
1778 | { |
1779 | return atomic_load(__p); |
1780 | } |
1781 | |
1782 | template <class _Tp> |
1783 | _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR |
1784 | void |
1785 | atomic_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 | |
1793 | template <class _Tp> |
1794 | inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
1795 | _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR |
1796 | void |
1797 | atomic_store_explicit(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r, memory_order) |
1798 | { |
1799 | atomic_store(__p, __r); |
1800 | } |
1801 | |
1802 | template <class _Tp> |
1803 | _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR |
1804 | shared_ptr<_Tp> |
1805 | atomic_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 | |
1814 | template <class _Tp> |
1815 | inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
1816 | _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR |
1817 | shared_ptr<_Tp> |
1818 | atomic_exchange_explicit(shared_ptr<_Tp>* __p, shared_ptr<_Tp> __r, memory_order) |
1819 | { |
1820 | return atomic_exchange(__p, __r); |
1821 | } |
1822 | |
1823 | template <class _Tp> |
1824 | _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR |
1825 | bool |
1826 | atomic_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 | |
1844 | template <class _Tp> |
1845 | inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
1846 | _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR |
1847 | bool |
1848 | atomic_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 | |
1853 | template <class _Tp> |
1854 | inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
1855 | _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR |
1856 | bool |
1857 | atomic_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 | |
1863 | template <class _Tp> |
1864 | inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
1865 | _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR |
1866 | bool |
1867 | atomic_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 |
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 | |
70 | namespace lldb { |
71 | |
72 | /// Process and Thread States. |
73 | enum 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. |
98 | FLAGS_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. |
135 | enum RunMode { eOnlyThisThread, eAllThreads, eOnlyDuringStepping }; |
136 | |
137 | /// Byte ordering definitions. |
138 | enum ByteOrder { |
139 | eByteOrderInvalid = 0, |
140 | eByteOrderBig = 1, |
141 | eByteOrderPDP = 2, |
142 | eByteOrderLittle = 4 |
143 | }; |
144 | |
145 | /// Register encoding definitions. |
146 | enum 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. |
155 | enum 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. |
207 | enum DescriptionLevel { |
208 | eDescriptionLevelBrief = 0, |
209 | eDescriptionLevelFull, |
210 | eDescriptionLevelVerbose, |
211 | eDescriptionLevelInitial, |
212 | kNumDescriptionLevels |
213 | }; |
214 | |
215 | /// Script interpreter types. |
216 | enum 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). |
227 | enum 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. |
239 | enum 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. |
258 | enum 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. |
270 | enum ExpressionResults { |
271 | eExpressionCompleted = 0, |
272 | eExpressionSetupError, |
273 | eExpressionParseError, |
274 | eExpressionDiscarded, |
275 | eExpressionInterrupted, |
276 | eExpressionHitBreakpoint, |
277 | eExpressionTimedOut, |
278 | eExpressionResultUnavailable, |
279 | eExpressionStoppedForDebug, |
280 | eExpressionThreadVanished |
281 | }; |
282 | |
283 | enum 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. |
295 | enum 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 | |
306 | enum 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 | |
315 | enum 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 | |
329 | enum 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. |
345 | FLAGS_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 | }; |
378 | LLDB_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; } |
379 | |
380 | FLAGS_ENUM(Permissions)enum Permissions : unsigned{ePermissionsWritable = (1u << 0), |
381 | ePermissionsReadable = (1u << 1), |
382 | ePermissionsExecutable = (1u << 2)}; |
383 | LLDB_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 | |
385 | enum 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 | |
401 | FLAGS_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 | |
418 | FLAGS_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. |
436 | enum 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 | |
485 | enum InstrumentationRuntimeType { |
486 | eInstrumentationRuntimeTypeAddressSanitizer = 0x0000, |
487 | eInstrumentationRuntimeTypeThreadSanitizer = 0x0001, |
488 | eInstrumentationRuntimeTypeUndefinedBehaviorSanitizer = 0x0002, |
489 | eInstrumentationRuntimeTypeMainThreadChecker = 0x0003, |
490 | eInstrumentationRuntimeTypeSwiftRuntimeReporting = 0x0004, |
491 | eNumInstrumentationRuntimeTypes |
492 | }; |
493 | |
494 | enum DynamicValueType { |
495 | eNoDynamicValues = 0, |
496 | eDynamicCanRunTarget = 1, |
497 | eDynamicDontRunTarget = 2 |
498 | }; |
499 | |
500 | enum StopShowColumn { |
501 | eStopShowColumnAnsiOrCaret = 0, |
502 | eStopShowColumnAnsi = 1, |
503 | eStopShowColumnCaret = 2, |
504 | eStopShowColumnNone = 3 |
505 | }; |
506 | |
507 | enum AccessType { |
508 | eAccessNone, |
509 | eAccessPublic, |
510 | eAccessPrivate, |
511 | eAccessProtected, |
512 | eAccessPackage |
513 | }; |
514 | |
515 | enum 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. |
612 | enum 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 | |
646 | enum 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 | |
712 | FLAGS_ENUM(EmulateInstructionOptions)enum EmulateInstructionOptions : unsigned{ |
713 | eEmulateInstructionOptionNone = (0u), |
714 | eEmulateInstructionOptionAutoAdvancePC = (1u << 0), |
715 | eEmulateInstructionOptionIgnoreConditions = (1u << 1)}; |
716 | |
717 | FLAGS_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 | }; |
738 | LLDB_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(). |
741 | enum 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 |
778 | enum TraceType { |
779 | eTraceTypeNone = 0, |
780 | |
781 | /// Intel Processor Trace |
782 | eTraceTypeProcessorTrace |
783 | }; |
784 | |
785 | enum StructuredDataType { |
786 | eStructuredDataTypeInvalid = -1, |
787 | eStructuredDataTypeNull = 0, |
788 | eStructuredDataTypeGeneric, |
789 | eStructuredDataTypeArray, |
790 | eStructuredDataTypeInteger, |
791 | eStructuredDataTypeFloat, |
792 | eStructuredDataTypeBoolean, |
793 | eStructuredDataTypeString, |
794 | eStructuredDataTypeDictionary |
795 | }; |
796 | |
797 | FLAGS_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)}; |
812 | LLDB_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 | |
814 | enum 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. |
828 | FLAGS_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. |
860 | enum 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. |
873 | FLAGS_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. |
933 | enum 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). |
944 | enum 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. |
955 | enum 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. |
966 | FLAGS_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 | |
979 | LLDB_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. |
985 | FLAGS_ENUM(WatchpointKind)enum WatchpointKind : unsigned{eWatchpointKindWrite = (1u << 0), |
986 | eWatchpointKindRead = (1u << 1)}; |
987 | |
988 | enum 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. |
1000 | enum 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. |
1020 | enum 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. |
1032 | enum MatchType { eMatchTypeNormal, eMatchTypeRegex, eMatchTypeStartsWith }; |
1033 | |
1034 | /// Bitmask that describes details about a type. |
1035 | FLAGS_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 | |
1049 | FLAGS_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. |
1116 | enum TypeSummaryCapping { |
1117 | eTypeSummaryCapped = true, |
1118 | eTypeSummaryUncapped = false |
1119 | }; |
1120 | |
1121 | /// The result from a command interpreter run. |
1122 | enum 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. |
1136 | enum SaveCoreStyle { |
1137 | eSaveCoreUnspecified = 0, |
1138 | eSaveCoreFull = 1, |
1139 | eSaveCoreDirtyOnly = 2, |
1140 | }; |
1141 | |
1142 | } // namespace lldb |
1143 | |
1144 | #endif // LLDB_LLDB_ENUMERATIONS_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 | |
37 | template <class _Tp> |
38 | struct _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 | |
61 | template <class _Tp> |
62 | struct _LIBCPP_TEMPLATE_VIS__attribute__ ((__type_visibility__("default"))) default_delete<_Tp[]> { |
63 | private: |
64 | template <class _Up> |
65 | struct _EnableIfConvertible |
66 | : enable_if<is_convertible<_Up(*)[], _Tp(*)[]>::value> {}; |
67 | |
68 | public: |
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 | |
92 | template <class _Deleter> |
93 | struct __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 | |
100 | template <class _Deleter> |
101 | struct __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 | |
107 | template <class _Deleter> |
108 | struct __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 | |
120 | template <class _Tp, class _Dp = default_delete<_Tp> > |
121 | class _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS__attribute__ ((__type_visibility__("default"))) unique_ptr { |
122 | public: |
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 | |
130 | private: |
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 | |
176 | public: |
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; |
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 | |
328 | template <class _Tp, class _Dp> |
329 | class _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS__attribute__ ((__type_visibility__("default"))) unique_ptr<_Tp[], _Dp> { |
330 | public: |
331 | typedef _Tp element_type; |
332 | typedef _Dp deleter_type; |
333 | typedef typename __pointer<_Tp, deleter_type>::type pointer; |
334 | |
335 | private: |
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 | |
399 | public: |
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 | |
493 | public: |
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 | |
561 | template <class _Tp, class _Dp> |
562 | inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
563 | typename enable_if< |
564 | __is_swappable<_Dp>::value, |
565 | void |
566 | >::type |
567 | swap(unique_ptr<_Tp, _Dp>& __x, unique_ptr<_Tp, _Dp>& __y) _NOEXCEPTnoexcept {__x.swap(__y);} |
568 | |
569 | template <class _T1, class _D1, class _T2, class _D2> |
570 | inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
571 | bool |
572 | operator==(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {return __x.get() == __y.get();} |
573 | |
574 | template <class _T1, class _D1, class _T2, class _D2> |
575 | inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
576 | bool |
577 | operator!=(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {return !(__x == __y);} |
578 | |
579 | template <class _T1, class _D1, class _T2, class _D2> |
580 | inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
581 | bool |
582 | operator< (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 | |
590 | template <class _T1, class _D1, class _T2, class _D2> |
591 | inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
592 | bool |
593 | operator> (const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {return __y < __x;} |
594 | |
595 | template <class _T1, class _D1, class _T2, class _D2> |
596 | inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
597 | bool |
598 | operator<=(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {return !(__y < __x);} |
599 | |
600 | template <class _T1, class _D1, class _T2, class _D2> |
601 | inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
602 | bool |
603 | operator>=(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {return !(__x < __y);} |
604 | |
605 | template <class _T1, class _D1> |
606 | inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
607 | bool |
608 | operator==(const unique_ptr<_T1, _D1>& __x, nullptr_t) _NOEXCEPTnoexcept |
609 | { |
610 | return !__x; |
611 | } |
612 | |
613 | template <class _T1, class _D1> |
614 | inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
615 | bool |
616 | operator==(nullptr_t, const unique_ptr<_T1, _D1>& __x) _NOEXCEPTnoexcept |
617 | { |
618 | return !__x; |
619 | } |
620 | |
621 | template <class _T1, class _D1> |
622 | inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
623 | bool |
624 | operator!=(const unique_ptr<_T1, _D1>& __x, nullptr_t) _NOEXCEPTnoexcept |
625 | { |
626 | return static_cast<bool>(__x); |
627 | } |
628 | |
629 | template <class _T1, class _D1> |
630 | inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
631 | bool |
632 | operator!=(nullptr_t, const unique_ptr<_T1, _D1>& __x) _NOEXCEPTnoexcept |
633 | { |
634 | return static_cast<bool>(__x); |
635 | } |
636 | |
637 | template <class _T1, class _D1> |
638 | inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
639 | bool |
640 | operator<(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 | |
646 | template <class _T1, class _D1> |
647 | inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
648 | bool |
649 | operator<(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 | |
655 | template <class _T1, class _D1> |
656 | inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
657 | bool |
658 | operator>(const unique_ptr<_T1, _D1>& __x, nullptr_t) |
659 | { |
660 | return nullptr < __x; |
661 | } |
662 | |
663 | template <class _T1, class _D1> |
664 | inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
665 | bool |
666 | operator>(nullptr_t, const unique_ptr<_T1, _D1>& __x) |
667 | { |
668 | return __x < nullptr; |
669 | } |
670 | |
671 | template <class _T1, class _D1> |
672 | inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
673 | bool |
674 | operator<=(const unique_ptr<_T1, _D1>& __x, nullptr_t) |
675 | { |
676 | return !(nullptr < __x); |
677 | } |
678 | |
679 | template <class _T1, class _D1> |
680 | inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
681 | bool |
682 | operator<=(nullptr_t, const unique_ptr<_T1, _D1>& __x) |
683 | { |
684 | return !(__x < nullptr); |
685 | } |
686 | |
687 | template <class _T1, class _D1> |
688 | inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
689 | bool |
690 | operator>=(const unique_ptr<_T1, _D1>& __x, nullptr_t) |
691 | { |
692 | return !(__x < nullptr); |
693 | } |
694 | |
695 | template <class _T1, class _D1> |
696 | inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
697 | bool |
698 | operator>=(nullptr_t, const unique_ptr<_T1, _D1>& __x) |
699 | { |
700 | return !(nullptr < __x); |
701 | } |
702 | |
703 | #if _LIBCPP_STD_VER14 > 11 |
704 | |
705 | template<class _Tp> |
706 | struct __unique_if |
707 | { |
708 | typedef unique_ptr<_Tp> __unique_single; |
709 | }; |
710 | |
711 | template<class _Tp> |
712 | struct __unique_if<_Tp[]> |
713 | { |
714 | typedef unique_ptr<_Tp[]> __unique_array_unknown_bound; |
715 | }; |
716 | |
717 | template<class _Tp, size_t _Np> |
718 | struct __unique_if<_Tp[_Np]> |
719 | { |
720 | typedef void __unique_array_known_bound; |
721 | }; |
722 | |
723 | template<class _Tp, class... _Args> |
724 | inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
725 | typename __unique_if<_Tp>::__unique_single |
726 | make_unique(_Args&&... __args) |
727 | { |
728 | return unique_ptr<_Tp>(new _Tp(_VSTDstd::__1::forward<_Args>(__args)...)); |
729 | } |
730 | |
731 | template<class _Tp> |
732 | inline _LIBCPP_INLINE_VISIBILITY__attribute__ ((__visibility__("hidden"))) __attribute__ ((__exclude_from_explicit_instantiation__ )) |
733 | typename __unique_if<_Tp>::__unique_array_unknown_bound |
734 | make_unique(size_t __n) |
735 | { |
736 | typedef typename remove_extent<_Tp>::type _Up; |
737 | return unique_ptr<_Tp>(new _Up[__n]()); |
738 | } |
739 | |
740 | template<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 | |
746 | template <class _Tp> struct _LIBCPP_TEMPLATE_VIS__attribute__ ((__type_visibility__("default"))) hash; |
747 | |
748 | template <class _Tp, class _Dp> |
749 | #ifdef _LIBCPP_CXX03_LANG |
750 | struct _LIBCPP_TEMPLATE_VIS__attribute__ ((__type_visibility__("default"))) hash<unique_ptr<_Tp, _Dp> > |
751 | #else |
752 |