File: | tools/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp |
Warning: | line 245, column 18 Potential leak of memory pointed to by field 'String' |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | //===-- PDBASTParser.cpp ----------------------------------------*- C++ -*-===// | |||
2 | // | |||
3 | // The LLVM Compiler Infrastructure | |||
4 | // | |||
5 | // This file is distributed under the University of Illinois Open Source | |||
6 | // License. See LICENSE.TXT for details. | |||
7 | // | |||
8 | //===----------------------------------------------------------------------===// | |||
9 | ||||
10 | #include "PDBASTParser.h" | |||
11 | ||||
12 | #include "clang/AST/CharUnits.h" | |||
13 | #include "clang/AST/Decl.h" | |||
14 | #include "clang/AST/DeclCXX.h" | |||
15 | ||||
16 | #include "lldb/Symbol/ClangASTContext.h" | |||
17 | #include "lldb/Symbol/ClangUtil.h" | |||
18 | #include "lldb/Symbol/Declaration.h" | |||
19 | #include "lldb/Symbol/SymbolFile.h" | |||
20 | #include "lldb/Symbol/TypeSystem.h" | |||
21 | ||||
22 | #include "llvm/DebugInfo/PDB/IPDBLineNumber.h" | |||
23 | #include "llvm/DebugInfo/PDB/IPDBSourceFile.h" | |||
24 | #include "llvm/DebugInfo/PDB/PDBSymbol.h" | |||
25 | #include "llvm/DebugInfo/PDB/PDBSymbolData.h" | |||
26 | #include "llvm/DebugInfo/PDB/PDBSymbolFunc.h" | |||
27 | #include "llvm/DebugInfo/PDB/PDBSymbolTypeArray.h" | |||
28 | #include "llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h" | |||
29 | #include "llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h" | |||
30 | #include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionArg.h" | |||
31 | #include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h" | |||
32 | #include "llvm/DebugInfo/PDB/PDBSymbolTypePointer.h" | |||
33 | #include "llvm/DebugInfo/PDB/PDBSymbolTypeTypedef.h" | |||
34 | #include "llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h" | |||
35 | ||||
36 | using namespace lldb; | |||
37 | using namespace lldb_private; | |||
38 | using namespace llvm::pdb; | |||
39 | ||||
40 | namespace { | |||
41 | int TranslateUdtKind(PDB_UdtType pdb_kind) { | |||
42 | switch (pdb_kind) { | |||
43 | case PDB_UdtType::Class: | |||
44 | return clang::TTK_Class; | |||
45 | case PDB_UdtType::Struct: | |||
46 | return clang::TTK_Struct; | |||
47 | case PDB_UdtType::Union: | |||
48 | return clang::TTK_Union; | |||
49 | case PDB_UdtType::Interface: | |||
50 | return clang::TTK_Interface; | |||
51 | } | |||
52 | return -1; | |||
53 | } | |||
54 | ||||
55 | lldb::Encoding TranslateBuiltinEncoding(PDB_BuiltinType type) { | |||
56 | switch (type) { | |||
57 | case PDB_BuiltinType::Float: | |||
58 | return lldb::eEncodingIEEE754; | |||
59 | case PDB_BuiltinType::Int: | |||
60 | case PDB_BuiltinType::Long: | |||
61 | case PDB_BuiltinType::Char: | |||
62 | return lldb::eEncodingSint; | |||
63 | case PDB_BuiltinType::Bool: | |||
64 | case PDB_BuiltinType::UInt: | |||
65 | case PDB_BuiltinType::ULong: | |||
66 | case PDB_BuiltinType::HResult: | |||
67 | return lldb::eEncodingUint; | |||
68 | default: | |||
69 | return lldb::eEncodingInvalid; | |||
70 | } | |||
71 | } | |||
72 | ||||
73 | lldb::Encoding TranslateEnumEncoding(PDB_VariantType type) { | |||
74 | switch (type) { | |||
75 | case PDB_VariantType::Int8: | |||
76 | case PDB_VariantType::Int16: | |||
77 | case PDB_VariantType::Int32: | |||
78 | case PDB_VariantType::Int64: | |||
79 | return lldb::eEncodingSint; | |||
80 | ||||
81 | case PDB_VariantType::UInt8: | |||
82 | case PDB_VariantType::UInt16: | |||
83 | case PDB_VariantType::UInt32: | |||
84 | case PDB_VariantType::UInt64: | |||
85 | return lldb::eEncodingUint; | |||
86 | ||||
87 | default: | |||
88 | break; | |||
89 | } | |||
90 | ||||
91 | return lldb::eEncodingSint; | |||
92 | } | |||
93 | ||||
94 | CompilerType GetBuiltinTypeForPDBEncodingAndBitSize( | |||
95 | ClangASTContext *clang_ast, const PDBSymbolTypeBuiltin *pdb_type, | |||
96 | Encoding encoding, uint32_t width) { | |||
97 | if (!pdb_type) | |||
98 | return CompilerType(); | |||
99 | if (!clang_ast) | |||
100 | return CompilerType(); | |||
101 | auto *ast = clang_ast->getASTContext(); | |||
102 | if (!ast) | |||
103 | return CompilerType(); | |||
104 | ||||
105 | switch (pdb_type->getBuiltinType()) { | |||
106 | default: break; | |||
107 | case PDB_BuiltinType::None: | |||
108 | return CompilerType(); | |||
109 | case PDB_BuiltinType::Void: | |||
110 | return clang_ast->GetBasicType(eBasicTypeVoid); | |||
111 | case PDB_BuiltinType::Bool: | |||
112 | return clang_ast->GetBasicType(eBasicTypeBool); | |||
113 | case PDB_BuiltinType::Long: | |||
114 | if (width == ast->getTypeSize(ast->LongTy)) | |||
115 | return CompilerType(ast, ast->LongTy); | |||
116 | if (width == ast->getTypeSize(ast->LongLongTy)) | |||
117 | return CompilerType(ast, ast->LongLongTy); | |||
118 | break; | |||
119 | case PDB_BuiltinType::ULong: | |||
120 | if (width == ast->getTypeSize(ast->UnsignedLongTy)) | |||
121 | return CompilerType(ast, ast->UnsignedLongTy); | |||
122 | if (width == ast->getTypeSize(ast->UnsignedLongLongTy)) | |||
123 | return CompilerType(ast, ast->UnsignedLongLongTy); | |||
124 | break; | |||
125 | case PDB_BuiltinType::WCharT: | |||
126 | if (width == ast->getTypeSize(ast->WCharTy)) | |||
127 | return CompilerType(ast, ast->WCharTy); | |||
128 | break; | |||
129 | case PDB_BuiltinType::Float: | |||
130 | // Note: types `long double` and `double` have same bit size in MSVC and there | |||
131 | // is no information in the PDB to distinguish them. So when falling back | |||
132 | // to default search, the compiler type of `long double` will be represented by | |||
133 | // the one generated for `double`. | |||
134 | break; | |||
135 | } | |||
136 | // If there is no match on PDB_BuiltinType, fall back to default search | |||
137 | // by encoding and width only | |||
138 | return clang_ast->GetBuiltinTypeForEncodingAndBitSize(encoding, width); | |||
139 | } | |||
140 | ||||
141 | ConstString GetPDBBuiltinTypeName(const PDBSymbolTypeBuiltin *pdb_type, | |||
142 | CompilerType &compiler_type) { | |||
143 | if (!pdb_type) | |||
144 | return compiler_type.GetTypeName(); | |||
145 | ||||
146 | PDB_BuiltinType kind = pdb_type->getBuiltinType(); | |||
147 | switch (kind) { | |||
148 | default: break; | |||
149 | case PDB_BuiltinType::Currency: | |||
150 | return ConstString("CURRENCY"); | |||
151 | case PDB_BuiltinType::Date: | |||
152 | return ConstString("DATE"); | |||
153 | case PDB_BuiltinType::Variant: | |||
154 | return ConstString("VARIANT"); | |||
155 | case PDB_BuiltinType::Complex: | |||
156 | return ConstString("complex"); | |||
157 | case PDB_BuiltinType::Bitfield: | |||
158 | return ConstString("bitfield"); | |||
159 | case PDB_BuiltinType::BSTR: | |||
160 | return ConstString("BSTR"); | |||
161 | case PDB_BuiltinType::HResult: | |||
162 | return ConstString("HRESULT"); | |||
163 | case PDB_BuiltinType::BCD: | |||
164 | return ConstString("BCD"); | |||
165 | case PDB_BuiltinType::None: | |||
166 | return ConstString("..."); | |||
167 | } | |||
168 | return compiler_type.GetTypeName(); | |||
169 | } | |||
170 | ||||
171 | bool GetDeclarationForSymbol(const PDBSymbol &symbol, Declaration &decl) { | |||
172 | auto &raw_sym = symbol.getRawSymbol(); | |||
173 | auto lines_up = symbol.getSession().findLineNumbersByAddress( | |||
174 | raw_sym.getVirtualAddress(), raw_sym.getLength()); | |||
175 | if (!lines_up) | |||
176 | return false; | |||
177 | auto first_line_up = lines_up->getNext(); | |||
178 | if (!first_line_up) | |||
179 | return false; | |||
180 | ||||
181 | uint32_t src_file_id = first_line_up->getSourceFileId(); | |||
182 | auto src_file_up = symbol.getSession().getSourceFileById(src_file_id); | |||
183 | if (!src_file_up) | |||
184 | return false; | |||
185 | ||||
186 | FileSpec spec(src_file_up->getFileName(), /*resolve_path*/false); | |||
187 | decl.SetFile(spec); | |||
188 | decl.SetColumn(first_line_up->getColumnNumber()); | |||
189 | decl.SetLine(first_line_up->getLineNumber()); | |||
190 | return true; | |||
191 | } | |||
192 | } | |||
193 | ||||
194 | PDBASTParser::PDBASTParser(lldb_private::ClangASTContext &ast) : m_ast(ast) {} | |||
195 | ||||
196 | PDBASTParser::~PDBASTParser() {} | |||
197 | ||||
198 | // DebugInfoASTParser interface | |||
199 | ||||
200 | lldb::TypeSP PDBASTParser::CreateLLDBTypeFromPDBType(const PDBSymbol &type) { | |||
201 | // PDB doesn't maintain enough information to robustly rebuild the entire | |||
202 | // tree, and this is most problematic when it comes to figure out the | |||
203 | // right DeclContext to put a type in. So for now, everything goes in | |||
204 | // the translation unit decl as a fully qualified type. | |||
205 | clang::DeclContext *tu_decl_ctx = m_ast.GetTranslationUnitDecl(); | |||
206 | Declaration decl; | |||
207 | ||||
208 | switch (type.getSymTag()) { | |||
| ||||
209 | case PDB_SymType::UDT: { | |||
210 | auto udt = llvm::dyn_cast<PDBSymbolTypeUDT>(&type); | |||
211 | assert(udt)(static_cast <bool> (udt) ? void (0) : __assert_fail ("udt" , "/build/llvm-toolchain-snapshot-7~svn326551/tools/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp" , 211, __extension__ __PRETTY_FUNCTION__)); | |||
212 | AccessType access = lldb::eAccessPublic; | |||
213 | PDB_UdtType udt_kind = udt->getUdtKind(); | |||
214 | auto tag_type_kind = TranslateUdtKind(udt_kind); | |||
215 | if (tag_type_kind == -1) | |||
216 | return nullptr; | |||
217 | ||||
218 | if (udt_kind == PDB_UdtType::Class) | |||
219 | access = lldb::eAccessPrivate; | |||
220 | ||||
221 | CompilerType clang_type = m_ast.CreateRecordType( | |||
222 | tu_decl_ctx, access, udt->getName().c_str(), tag_type_kind, | |||
223 | lldb::eLanguageTypeC_plus_plus, nullptr); | |||
224 | ||||
225 | m_ast.SetHasExternalStorage(clang_type.GetOpaqueQualType(), true); | |||
226 | ||||
227 | return std::make_shared<lldb_private::Type>( | |||
228 | type.getSymIndexId(), m_ast.GetSymbolFile(), | |||
229 | ConstString(udt->getName()), udt->getLength(), nullptr, | |||
230 | LLDB_INVALID_UID(18446744073709551615UL), lldb_private::Type::eEncodingIsUID, decl, clang_type, | |||
231 | lldb_private::Type::eResolveStateForward); | |||
232 | } break; | |||
233 | case PDB_SymType::Enum: { | |||
234 | auto enum_type = llvm::dyn_cast<PDBSymbolTypeEnum>(&type); | |||
235 | assert(enum_type)(static_cast <bool> (enum_type) ? void (0) : __assert_fail ("enum_type", "/build/llvm-toolchain-snapshot-7~svn326551/tools/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp" , 235, __extension__ __PRETTY_FUNCTION__)); | |||
236 | auto underlying_type_up = enum_type->getUnderlyingType(); | |||
237 | if (!underlying_type_up) | |||
238 | return nullptr; | |||
239 | lldb::Encoding encoding = | |||
240 | TranslateBuiltinEncoding(underlying_type_up->getBuiltinType()); | |||
241 | // FIXME: Type of underlying builtin is always `Int`. We correct it with | |||
242 | // the very first enumerator's encoding if any. | |||
243 | auto first_child = enum_type->findOneChild<PDBSymbolData>(); | |||
244 | if (first_child) { | |||
245 | encoding = TranslateEnumEncoding(first_child->getValue().Type); | |||
| ||||
246 | } | |||
247 | std::string name = enum_type->getName(); | |||
248 | uint64_t bytes = enum_type->getLength(); | |||
249 | CompilerType builtin_type; | |||
250 | if (bytes > 0) | |||
251 | builtin_type = GetBuiltinTypeForPDBEncodingAndBitSize( | |||
252 | &m_ast, underlying_type_up.get(), encoding, bytes * 8); | |||
253 | else | |||
254 | builtin_type = m_ast.GetBasicType(eBasicTypeInt); | |||
255 | // FIXME: PDB does not have information about scoped enumeration (Enum Class). | |||
256 | // Set it false for now. | |||
257 | bool isScoped = false; | |||
258 | ||||
259 | CompilerType ast_enum = m_ast.CreateEnumerationType( | |||
260 | name.c_str(), tu_decl_ctx, decl, builtin_type, isScoped); | |||
261 | auto enum_values = enum_type->findAllChildren<PDBSymbolData>(); | |||
262 | if (enum_values) { | |||
263 | while (auto enum_value = enum_values->getNext()) { | |||
264 | if (enum_value->getDataKind() != PDB_DataKind::Constant) | |||
265 | continue; | |||
266 | AddEnumValue(ast_enum, *enum_value); | |||
267 | } | |||
268 | } | |||
269 | if (ClangASTContext::StartTagDeclarationDefinition(ast_enum)) | |||
270 | ClangASTContext::CompleteTagDeclarationDefinition(ast_enum); | |||
271 | ||||
272 | return std::make_shared<lldb_private::Type>( | |||
273 | type.getSymIndexId(), m_ast.GetSymbolFile(), ConstString(name), bytes, | |||
274 | nullptr, LLDB_INVALID_UID(18446744073709551615UL), lldb_private::Type::eEncodingIsUID, decl, | |||
275 | ast_enum, lldb_private::Type::eResolveStateFull); | |||
276 | } break; | |||
277 | case PDB_SymType::Typedef: { | |||
278 | auto type_def = llvm::dyn_cast<PDBSymbolTypeTypedef>(&type); | |||
279 | assert(type_def)(static_cast <bool> (type_def) ? void (0) : __assert_fail ("type_def", "/build/llvm-toolchain-snapshot-7~svn326551/tools/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp" , 279, __extension__ __PRETTY_FUNCTION__)); | |||
280 | lldb_private::Type *target_type = | |||
281 | m_ast.GetSymbolFile()->ResolveTypeUID(type_def->getTypeId()); | |||
282 | if (!target_type) | |||
283 | return nullptr; | |||
284 | std::string name = type_def->getName(); | |||
285 | uint64_t bytes = type_def->getLength(); | |||
286 | CompilerType target_ast_type = target_type->GetFullCompilerType(); | |||
287 | CompilerDeclContext target_decl_ctx = | |||
288 | m_ast.GetSymbolFile()->GetDeclContextForUID(target_type->GetID()); | |||
289 | CompilerType ast_typedef = | |||
290 | m_ast.CreateTypedefType(target_ast_type, name.c_str(), target_decl_ctx); | |||
291 | return std::make_shared<lldb_private::Type>( | |||
292 | type_def->getSymIndexId(), m_ast.GetSymbolFile(), ConstString(name), | |||
293 | bytes, nullptr, target_type->GetID(), | |||
294 | lldb_private::Type::eEncodingIsTypedefUID, decl, ast_typedef, | |||
295 | lldb_private::Type::eResolveStateFull); | |||
296 | } break; | |||
297 | case PDB_SymType::Function: | |||
298 | case PDB_SymType::FunctionSig: { | |||
299 | std::string name; | |||
300 | PDBSymbolTypeFunctionSig *func_sig = nullptr; | |||
301 | if (auto pdb_func = llvm::dyn_cast<PDBSymbolFunc>(&type)) { | |||
302 | auto sig = pdb_func->getSignature(); | |||
303 | if (!sig) | |||
304 | return nullptr; | |||
305 | func_sig = sig.release(); | |||
306 | // Function type is named. | |||
307 | name = pdb_func->getName(); | |||
308 | } else if (auto pdb_func_sig = | |||
309 | llvm::dyn_cast<PDBSymbolTypeFunctionSig>(&type)) { | |||
310 | func_sig = const_cast<PDBSymbolTypeFunctionSig*>(pdb_func_sig); | |||
311 | } else | |||
312 | llvm_unreachable("Unexpected PDB symbol!")::llvm::llvm_unreachable_internal("Unexpected PDB symbol!", "/build/llvm-toolchain-snapshot-7~svn326551/tools/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp" , 312); | |||
313 | ||||
314 | auto arg_enum = func_sig->getArguments(); | |||
315 | uint32_t num_args = arg_enum->getChildCount(); | |||
316 | std::vector<CompilerType> arg_list; | |||
317 | ||||
318 | bool is_variadic = func_sig->isCVarArgs(); | |||
319 | // Drop last variadic argument. | |||
320 | if (is_variadic) | |||
321 | --num_args; | |||
322 | for (uint32_t arg_idx = 0; arg_idx < num_args; arg_idx++) { | |||
323 | auto arg = arg_enum->getChildAtIndex(arg_idx); | |||
324 | if (!arg) | |||
325 | break; | |||
326 | lldb_private::Type *arg_type = | |||
327 | m_ast.GetSymbolFile()->ResolveTypeUID(arg->getSymIndexId()); | |||
328 | // If there's some error looking up one of the dependent types of this | |||
329 | // function signature, bail. | |||
330 | if (!arg_type) | |||
331 | return nullptr; | |||
332 | CompilerType arg_ast_type = arg_type->GetFullCompilerType(); | |||
333 | arg_list.push_back(arg_ast_type); | |||
334 | } | |||
335 | lldbassert(arg_list.size() <= num_args)lldb_private::lldb_assert(arg_list.size() <= num_args, "arg_list.size() <= num_args" , __FUNCTION__, "/build/llvm-toolchain-snapshot-7~svn326551/tools/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp" , 335); | |||
336 | ||||
337 | auto pdb_return_type = func_sig->getReturnType(); | |||
338 | lldb_private::Type *return_type = | |||
339 | m_ast.GetSymbolFile()->ResolveTypeUID(pdb_return_type->getSymIndexId()); | |||
340 | // If there's some error looking up one of the dependent types of this | |||
341 | // function signature, bail. | |||
342 | if (!return_type) | |||
343 | return nullptr; | |||
344 | CompilerType return_ast_type = return_type->GetFullCompilerType(); | |||
345 | uint32_t type_quals = 0; | |||
346 | if (func_sig->isConstType()) | |||
347 | type_quals |= clang::Qualifiers::Const; | |||
348 | if (func_sig->isVolatileType()) | |||
349 | type_quals |= clang::Qualifiers::Volatile; | |||
350 | CompilerType func_sig_ast_type = m_ast.CreateFunctionType( | |||
351 | return_ast_type, arg_list.data(), arg_list.size(), is_variadic, | |||
352 | type_quals); | |||
353 | ||||
354 | GetDeclarationForSymbol(type, decl); | |||
355 | return std::make_shared<lldb_private::Type>( | |||
356 | type.getSymIndexId(), m_ast.GetSymbolFile(), ConstString(name), 0, | |||
357 | nullptr, LLDB_INVALID_UID(18446744073709551615UL), lldb_private::Type::eEncodingIsUID, decl, | |||
358 | func_sig_ast_type, lldb_private::Type::eResolveStateFull); | |||
359 | } break; | |||
360 | case PDB_SymType::ArrayType: { | |||
361 | auto array_type = llvm::dyn_cast<PDBSymbolTypeArray>(&type); | |||
362 | assert(array_type)(static_cast <bool> (array_type) ? void (0) : __assert_fail ("array_type", "/build/llvm-toolchain-snapshot-7~svn326551/tools/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp" , 362, __extension__ __PRETTY_FUNCTION__)); | |||
363 | uint32_t num_elements = array_type->getCount(); | |||
364 | uint32_t element_uid = array_type->getElementType()->getSymIndexId(); | |||
365 | uint32_t bytes = array_type->getLength(); | |||
366 | ||||
367 | lldb_private::Type *element_type = | |||
368 | m_ast.GetSymbolFile()->ResolveTypeUID(element_uid); | |||
369 | if (!element_type) | |||
370 | return nullptr; | |||
371 | CompilerType element_ast_type = element_type->GetFullCompilerType(); | |||
372 | CompilerType array_ast_type = | |||
373 | m_ast.CreateArrayType(element_ast_type, num_elements, false); | |||
374 | return std::make_shared<lldb_private::Type>( | |||
375 | array_type->getSymIndexId(), m_ast.GetSymbolFile(), ConstString(), | |||
376 | bytes, nullptr, LLDB_INVALID_UID(18446744073709551615UL), lldb_private::Type::eEncodingIsUID, | |||
377 | decl, array_ast_type, lldb_private::Type::eResolveStateFull); | |||
378 | } break; | |||
379 | case PDB_SymType::BuiltinType: { | |||
380 | auto *builtin_type = llvm::dyn_cast<PDBSymbolTypeBuiltin>(&type); | |||
381 | assert(builtin_type)(static_cast <bool> (builtin_type) ? void (0) : __assert_fail ("builtin_type", "/build/llvm-toolchain-snapshot-7~svn326551/tools/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp" , 381, __extension__ __PRETTY_FUNCTION__)); | |||
382 | PDB_BuiltinType builtin_kind = builtin_type->getBuiltinType(); | |||
383 | if (builtin_kind == PDB_BuiltinType::None) | |||
384 | return nullptr; | |||
385 | ||||
386 | uint64_t bytes = builtin_type->getLength(); | |||
387 | Encoding encoding = TranslateBuiltinEncoding(builtin_kind); | |||
388 | CompilerType builtin_ast_type = GetBuiltinTypeForPDBEncodingAndBitSize( | |||
389 | &m_ast, builtin_type, encoding, bytes * 8); | |||
390 | ||||
391 | Type::EncodingDataType encoding_data_type = Type::eEncodingIsUID; | |||
392 | if (builtin_type->isConstType()) { | |||
393 | encoding_data_type = Type::eEncodingIsConstUID; | |||
394 | builtin_ast_type = builtin_ast_type.AddConstModifier(); | |||
395 | } | |||
396 | if (builtin_type->isVolatileType()) { | |||
397 | encoding_data_type = Type::eEncodingIsVolatileUID; | |||
398 | builtin_ast_type = builtin_ast_type.AddVolatileModifier(); | |||
399 | } | |||
400 | auto type_name = GetPDBBuiltinTypeName(builtin_type, builtin_ast_type); | |||
401 | ||||
402 | return std::make_shared<lldb_private::Type>( | |||
403 | builtin_type->getSymIndexId(), m_ast.GetSymbolFile(), type_name, | |||
404 | bytes, nullptr, LLDB_INVALID_UID(18446744073709551615UL), encoding_data_type, | |||
405 | decl, builtin_ast_type, lldb_private::Type::eResolveStateFull); | |||
406 | } break; | |||
407 | case PDB_SymType::PointerType: { | |||
408 | auto *pointer_type = llvm::dyn_cast<PDBSymbolTypePointer>(&type); | |||
409 | assert(pointer_type)(static_cast <bool> (pointer_type) ? void (0) : __assert_fail ("pointer_type", "/build/llvm-toolchain-snapshot-7~svn326551/tools/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp" , 409, __extension__ __PRETTY_FUNCTION__)); | |||
410 | Type *pointee_type = m_ast.GetSymbolFile()->ResolveTypeUID( | |||
411 | pointer_type->getPointeeType()->getSymIndexId()); | |||
412 | if (!pointee_type) | |||
413 | return nullptr; | |||
414 | ||||
415 | CompilerType pointer_ast_type; | |||
416 | Type::EncodingDataType encoding_data_type = Type::eEncodingIsPointerUID; | |||
417 | if (pointer_type->isReference()) { | |||
418 | encoding_data_type = Type::eEncodingIsLValueReferenceUID; | |||
419 | pointer_ast_type = | |||
420 | pointee_type->GetFullCompilerType().GetLValueReferenceType(); | |||
421 | } else | |||
422 | pointer_ast_type = pointee_type->GetFullCompilerType().GetPointerType(); | |||
423 | ||||
424 | return std::make_shared<lldb_private::Type>( | |||
425 | pointer_type->getSymIndexId(), m_ast.GetSymbolFile(), ConstString(), | |||
426 | pointer_type->getLength(), nullptr, LLDB_INVALID_UID(18446744073709551615UL), | |||
427 | encoding_data_type, decl, pointer_ast_type, | |||
428 | lldb_private::Type::eResolveStateFull); | |||
429 | } break; | |||
430 | default: break; | |||
431 | } | |||
432 | return nullptr; | |||
433 | } | |||
434 | ||||
435 | bool PDBASTParser::AddEnumValue(CompilerType enum_type, | |||
436 | const PDBSymbolData &enum_value) const { | |||
437 | Declaration decl; | |||
438 | Variant v = enum_value.getValue(); | |||
439 | std::string name = enum_value.getName(); | |||
440 | int64_t raw_value; | |||
441 | switch (v.Type) { | |||
442 | case PDB_VariantType::Int8: | |||
443 | raw_value = v.Value.Int8; | |||
444 | break; | |||
445 | case PDB_VariantType::Int16: | |||
446 | raw_value = v.Value.Int16; | |||
447 | break; | |||
448 | case PDB_VariantType::Int32: | |||
449 | raw_value = v.Value.Int32; | |||
450 | break; | |||
451 | case PDB_VariantType::Int64: | |||
452 | raw_value = v.Value.Int64; | |||
453 | break; | |||
454 | case PDB_VariantType::UInt8: | |||
455 | raw_value = v.Value.UInt8; | |||
456 | break; | |||
457 | case PDB_VariantType::UInt16: | |||
458 | raw_value = v.Value.UInt16; | |||
459 | break; | |||
460 | case PDB_VariantType::UInt32: | |||
461 | raw_value = v.Value.UInt32; | |||
462 | break; | |||
463 | case PDB_VariantType::UInt64: | |||
464 | raw_value = v.Value.UInt64; | |||
465 | break; | |||
466 | default: | |||
467 | return false; | |||
468 | } | |||
469 | CompilerType underlying_type = | |||
470 | m_ast.GetEnumerationIntegerType(enum_type.GetOpaqueQualType()); | |||
471 | uint32_t byte_size = m_ast.getASTContext()->getTypeSize( | |||
472 | ClangUtil::GetQualType(underlying_type)); | |||
473 | return m_ast.AddEnumerationValueToEnumerationType( | |||
474 | enum_type.GetOpaqueQualType(), underlying_type, decl, name.c_str(), | |||
475 | raw_value, byte_size * 8); | |||
476 | } |
1 | //===- PDBSymbolData.h - PDB data (e.g. variable) accessors -----*- C++ -*-===// |
2 | // |
3 | // The LLVM Compiler Infrastructure |
4 | // |
5 | // This file is distributed under the University of Illinois Open Source |
6 | // License. See LICENSE.TXT for details. |
7 | // |
8 | //===----------------------------------------------------------------------===// |
9 | |
10 | #ifndef LLVM_DEBUGINFO_PDB_PDBSYMBOLDATA_H |
11 | #define LLVM_DEBUGINFO_PDB_PDBSYMBOLDATA_H |
12 | |
13 | #include "PDBSymbol.h" |
14 | #include "PDBTypes.h" |
15 | |
16 | namespace llvm { |
17 | |
18 | class raw_ostream; |
19 | |
20 | namespace pdb { |
21 | |
22 | class PDBSymbolData : public PDBSymbol { |
23 | public: |
24 | PDBSymbolData(const IPDBSession &PDBSession, |
25 | std::unique_ptr<IPDBRawSymbol> DataSymbol); |
26 | |
27 | DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::Data)static const PDB_SymType Tag = PDB_SymType::Data; static bool classof(const PDBSymbol *S) { return S->getSymTag() == Tag ; } |
28 | |
29 | void dump(PDBSymDumper &Dumper) const override; |
30 | |
31 | FORWARD_SYMBOL_METHOD(getAccess)auto getAccess() const->decltype(RawSymbol->getAccess() ) { return RawSymbol->getAccess(); } |
32 | FORWARD_SYMBOL_METHOD(getAddressOffset)auto getAddressOffset() const->decltype(RawSymbol->getAddressOffset ()) { return RawSymbol->getAddressOffset(); } |
33 | FORWARD_SYMBOL_METHOD(getAddressSection)auto getAddressSection() const->decltype(RawSymbol->getAddressSection ()) { return RawSymbol->getAddressSection(); } |
34 | FORWARD_SYMBOL_METHOD(getAddressTaken)auto getAddressTaken() const->decltype(RawSymbol->getAddressTaken ()) { return RawSymbol->getAddressTaken(); } |
35 | FORWARD_SYMBOL_METHOD(getBitPosition)auto getBitPosition() const->decltype(RawSymbol->getBitPosition ()) { return RawSymbol->getBitPosition(); } |
36 | FORWARD_SYMBOL_ID_METHOD(getClassParent)auto getClassParentId() const->decltype(RawSymbol->getClassParentId ()) { return RawSymbol->getClassParentId(); } std::unique_ptr <PDBSymbol> getClassParent() const { uint32_t Id = getClassParentId (); return getConcreteSymbolByIdHelper<PDBSymbol>(Id); } |
37 | FORWARD_SYMBOL_METHOD(isCompilerGenerated)auto isCompilerGenerated() const->decltype(RawSymbol->isCompilerGenerated ()) { return RawSymbol->isCompilerGenerated(); } |
38 | FORWARD_SYMBOL_METHOD(isConstType)auto isConstType() const->decltype(RawSymbol->isConstType ()) { return RawSymbol->isConstType(); } |
39 | FORWARD_SYMBOL_METHOD(getDataKind)auto getDataKind() const->decltype(RawSymbol->getDataKind ()) { return RawSymbol->getDataKind(); } |
40 | FORWARD_SYMBOL_METHOD(isAggregated)auto isAggregated() const->decltype(RawSymbol->isAggregated ()) { return RawSymbol->isAggregated(); } |
41 | FORWARD_SYMBOL_METHOD(isSplitted)auto isSplitted() const->decltype(RawSymbol->isSplitted ()) { return RawSymbol->isSplitted(); } |
42 | FORWARD_SYMBOL_METHOD(getLength)auto getLength() const->decltype(RawSymbol->getLength() ) { return RawSymbol->getLength(); } |
43 | FORWARD_SYMBOL_ID_METHOD(getLexicalParent)auto getLexicalParentId() const->decltype(RawSymbol->getLexicalParentId ()) { return RawSymbol->getLexicalParentId(); } std::unique_ptr <PDBSymbol> getLexicalParent() const { uint32_t Id = getLexicalParentId (); return getConcreteSymbolByIdHelper<PDBSymbol>(Id); } |
44 | FORWARD_SYMBOL_METHOD(getLocationType)auto getLocationType() const->decltype(RawSymbol->getLocationType ()) { return RawSymbol->getLocationType(); } |
45 | FORWARD_SYMBOL_METHOD(getName)auto getName() const->decltype(RawSymbol->getName()) { return RawSymbol->getName(); } |
46 | FORWARD_SYMBOL_METHOD(getOffset)auto getOffset() const->decltype(RawSymbol->getOffset() ) { return RawSymbol->getOffset(); } |
47 | FORWARD_SYMBOL_METHOD(getRegisterId)auto getRegisterId() const->decltype(RawSymbol->getRegisterId ()) { return RawSymbol->getRegisterId(); } |
48 | FORWARD_SYMBOL_METHOD(getRelativeVirtualAddress)auto getRelativeVirtualAddress() const->decltype(RawSymbol ->getRelativeVirtualAddress()) { return RawSymbol->getRelativeVirtualAddress (); } |
49 | FORWARD_SYMBOL_METHOD(getSlot)auto getSlot() const->decltype(RawSymbol->getSlot()) { return RawSymbol->getSlot(); } |
50 | FORWARD_SYMBOL_METHOD(getToken)auto getToken() const->decltype(RawSymbol->getToken()) { return RawSymbol->getToken(); } |
51 | FORWARD_SYMBOL_ID_METHOD(getType)auto getTypeId() const->decltype(RawSymbol->getTypeId() ) { return RawSymbol->getTypeId(); } std::unique_ptr<PDBSymbol > getType() const { uint32_t Id = getTypeId(); return getConcreteSymbolByIdHelper <PDBSymbol>(Id); } |
52 | FORWARD_SYMBOL_METHOD(isUnalignedType)auto isUnalignedType() const->decltype(RawSymbol->isUnalignedType ()) { return RawSymbol->isUnalignedType(); } |
53 | FORWARD_SYMBOL_METHOD(getValue)auto getValue() const->decltype(RawSymbol->getValue()) { return RawSymbol->getValue(); } |
54 | FORWARD_SYMBOL_METHOD(getVirtualAddress)auto getVirtualAddress() const->decltype(RawSymbol->getVirtualAddress ()) { return RawSymbol->getVirtualAddress(); } |
55 | FORWARD_SYMBOL_METHOD(isVolatileType)auto isVolatileType() const->decltype(RawSymbol->isVolatileType ()) { return RawSymbol->isVolatileType(); } |
56 | }; |
57 | |
58 | } // namespace llvm |
59 | } |
60 | |
61 | #endif // LLVM_DEBUGINFO_PDB_PDBSYMBOLDATA_H |
1 | //===- PDBTypes.h - Defines enums for various fields contained in PDB ----====// |
2 | // |
3 | // The LLVM Compiler Infrastructure |
4 | // |
5 | // This file is distributed under the University of Illinois Open Source |
6 | // License. See LICENSE.TXT for details. |
7 | // |
8 | //===----------------------------------------------------------------------===// |
9 | |
10 | #ifndef LLVM_DEBUGINFO_PDB_PDBTYPES_H |
11 | #define LLVM_DEBUGINFO_PDB_PDBTYPES_H |
12 | |
13 | #include "llvm/DebugInfo/CodeView/CodeView.h" |
14 | #include "llvm/DebugInfo/PDB/IPDBEnumChildren.h" |
15 | #include "llvm/DebugInfo/PDB/Native/RawTypes.h" |
16 | #include <cctype> |
17 | #include <cstddef> |
18 | #include <cstdint> |
19 | #include <cstring> |
20 | #include <functional> |
21 | |
22 | namespace llvm { |
23 | namespace pdb { |
24 | |
25 | class IPDBDataStream; |
26 | class IPDBLineNumber; |
27 | class IPDBSourceFile; |
28 | class IPDBTable; |
29 | class PDBSymDumper; |
30 | class PDBSymbol; |
31 | class PDBSymbolExe; |
32 | class PDBSymbolCompiland; |
33 | class PDBSymbolCompilandDetails; |
34 | class PDBSymbolCompilandEnv; |
35 | class PDBSymbolFunc; |
36 | class PDBSymbolBlock; |
37 | class PDBSymbolData; |
38 | class PDBSymbolAnnotation; |
39 | class PDBSymbolLabel; |
40 | class PDBSymbolPublicSymbol; |
41 | class PDBSymbolTypeUDT; |
42 | class PDBSymbolTypeEnum; |
43 | class PDBSymbolTypeFunctionSig; |
44 | class PDBSymbolTypePointer; |
45 | class PDBSymbolTypeArray; |
46 | class PDBSymbolTypeBuiltin; |
47 | class PDBSymbolTypeTypedef; |
48 | class PDBSymbolTypeBaseClass; |
49 | class PDBSymbolTypeFriend; |
50 | class PDBSymbolTypeFunctionArg; |
51 | class PDBSymbolFuncDebugStart; |
52 | class PDBSymbolFuncDebugEnd; |
53 | class PDBSymbolUsingNamespace; |
54 | class PDBSymbolTypeVTableShape; |
55 | class PDBSymbolTypeVTable; |
56 | class PDBSymbolCustom; |
57 | class PDBSymbolThunk; |
58 | class PDBSymbolTypeCustom; |
59 | class PDBSymbolTypeManaged; |
60 | class PDBSymbolTypeDimension; |
61 | class PDBSymbolUnknown; |
62 | |
63 | using IPDBEnumSymbols = IPDBEnumChildren<PDBSymbol>; |
64 | using IPDBEnumSourceFiles = IPDBEnumChildren<IPDBSourceFile>; |
65 | using IPDBEnumDataStreams = IPDBEnumChildren<IPDBDataStream>; |
66 | using IPDBEnumLineNumbers = IPDBEnumChildren<IPDBLineNumber>; |
67 | using IPDBEnumTables = IPDBEnumChildren<IPDBTable>; |
68 | |
69 | /// Specifies which PDB reader implementation is to be used. Only a value |
70 | /// of PDB_ReaderType::DIA is currently supported, but Native is in the works. |
71 | enum class PDB_ReaderType { |
72 | DIA = 0, |
73 | Native = 1, |
74 | }; |
75 | |
76 | /// An enumeration indicating the type of data contained in this table. |
77 | enum class PDB_TableType { |
78 | TableInvalid = 0, |
79 | Symbols, |
80 | SourceFiles, |
81 | LineNumbers, |
82 | SectionContribs, |
83 | Segments, |
84 | InjectedSources, |
85 | FrameData, |
86 | InputAssemblyFiles, |
87 | Dbg |
88 | }; |
89 | |
90 | /// Defines flags used for enumerating child symbols. This corresponds to the |
91 | /// NameSearchOptions enumeration which is documented here: |
92 | /// https://msdn.microsoft.com/en-us/library/yat28ads.aspx |
93 | enum PDB_NameSearchFlags { |
94 | NS_Default = 0x0, |
95 | NS_CaseSensitive = 0x1, |
96 | NS_CaseInsensitive = 0x2, |
97 | NS_FileNameExtMatch = 0x4, |
98 | NS_Regex = 0x8, |
99 | NS_UndecoratedName = 0x10 |
100 | }; |
101 | |
102 | /// Specifies the hash algorithm that a source file from a PDB was hashed with. |
103 | /// This corresponds to the CV_SourceChksum_t enumeration and are documented |
104 | /// here: https://msdn.microsoft.com/en-us/library/e96az21x.aspx |
105 | enum class PDB_Checksum { None = 0, MD5 = 1, SHA1 = 2 }; |
106 | |
107 | /// These values correspond to the CV_CPU_TYPE_e enumeration, and are documented |
108 | /// here: https://msdn.microsoft.com/en-us/library/b2fc64ek.aspx |
109 | using PDB_Cpu = codeview::CPUType; |
110 | |
111 | enum class PDB_Machine { |
112 | Invalid = 0xffff, |
113 | Unknown = 0x0, |
114 | Am33 = 0x13, |
115 | Amd64 = 0x8664, |
116 | Arm = 0x1C0, |
117 | ArmNT = 0x1C4, |
118 | Ebc = 0xEBC, |
119 | x86 = 0x14C, |
120 | Ia64 = 0x200, |
121 | M32R = 0x9041, |
122 | Mips16 = 0x266, |
123 | MipsFpu = 0x366, |
124 | MipsFpu16 = 0x466, |
125 | PowerPC = 0x1F0, |
126 | PowerPCFP = 0x1F1, |
127 | R4000 = 0x166, |
128 | SH3 = 0x1A2, |
129 | SH3DSP = 0x1A3, |
130 | SH4 = 0x1A6, |
131 | SH5 = 0x1A8, |
132 | Thumb = 0x1C2, |
133 | WceMipsV2 = 0x169 |
134 | }; |
135 | |
136 | /// These values correspond to the CV_call_e enumeration, and are documented |
137 | /// at the following locations: |
138 | /// https://msdn.microsoft.com/en-us/library/b2fc64ek.aspx |
139 | /// https://msdn.microsoft.com/en-us/library/windows/desktop/ms680207(v=vs.85).aspx |
140 | using PDB_CallingConv = codeview::CallingConvention; |
141 | |
142 | /// These values correspond to the CV_CFL_LANG enumeration, and are documented |
143 | /// here: https://msdn.microsoft.com/en-us/library/bw3aekw6.aspx |
144 | using PDB_Lang = codeview::SourceLanguage; |
145 | |
146 | /// These values correspond to the DataKind enumeration, and are documented |
147 | /// here: https://msdn.microsoft.com/en-us/library/b2x2t313.aspx |
148 | enum class PDB_DataKind { |
149 | Unknown, |
150 | Local, |
151 | StaticLocal, |
152 | Param, |
153 | ObjectPtr, |
154 | FileStatic, |
155 | Global, |
156 | Member, |
157 | StaticMember, |
158 | Constant |
159 | }; |
160 | |
161 | /// These values correspond to the SymTagEnum enumeration, and are documented |
162 | /// here: https://msdn.microsoft.com/en-us/library/bkedss5f.aspx |
163 | enum class PDB_SymType { |
164 | None, |
165 | Exe, |
166 | Compiland, |
167 | CompilandDetails, |
168 | CompilandEnv, |
169 | Function, |
170 | Block, |
171 | Data, |
172 | Annotation, |
173 | Label, |
174 | PublicSymbol, |
175 | UDT, |
176 | Enum, |
177 | FunctionSig, |
178 | PointerType, |
179 | ArrayType, |
180 | BuiltinType, |
181 | Typedef, |
182 | BaseClass, |
183 | Friend, |
184 | FunctionArg, |
185 | FuncDebugStart, |
186 | FuncDebugEnd, |
187 | UsingNamespace, |
188 | VTableShape, |
189 | VTable, |
190 | Custom, |
191 | Thunk, |
192 | CustomType, |
193 | ManagedType, |
194 | Dimension, |
195 | Max |
196 | }; |
197 | |
198 | /// These values correspond to the LocationType enumeration, and are documented |
199 | /// here: https://msdn.microsoft.com/en-us/library/f57kaez3.aspx |
200 | enum class PDB_LocType { |
201 | Null, |
202 | Static, |
203 | TLS, |
204 | RegRel, |
205 | ThisRel, |
206 | Enregistered, |
207 | BitField, |
208 | Slot, |
209 | IlRel, |
210 | MetaData, |
211 | Constant, |
212 | Max |
213 | }; |
214 | |
215 | /// These values correspond to the UdtKind enumeration, and are documented |
216 | /// here: https://msdn.microsoft.com/en-us/library/wcstk66t.aspx |
217 | enum class PDB_UdtType { Struct, Class, Union, Interface }; |
218 | |
219 | /// These values correspond to the StackFrameTypeEnum enumeration, and are |
220 | /// documented here: https://msdn.microsoft.com/en-us/library/bc5207xw.aspx. |
221 | enum class PDB_StackFrameType { FPO, KernelTrap, KernelTSS, EBP, FrameData }; |
222 | |
223 | /// These values correspond to the StackFrameTypeEnum enumeration, and are |
224 | /// documented here: https://msdn.microsoft.com/en-us/library/bc5207xw.aspx. |
225 | enum class PDB_MemoryType { Code, Data, Stack, HeapCode }; |
226 | |
227 | /// These values correspond to the Basictype enumeration, and are documented |
228 | /// here: https://msdn.microsoft.com/en-us/library/4szdtzc3.aspx |
229 | enum class PDB_BuiltinType { |
230 | None = 0, |
231 | Void = 1, |
232 | Char = 2, |
233 | WCharT = 3, |
234 | Int = 6, |
235 | UInt = 7, |
236 | Float = 8, |
237 | BCD = 9, |
238 | Bool = 10, |
239 | Long = 13, |
240 | ULong = 14, |
241 | Currency = 25, |
242 | Date = 26, |
243 | Variant = 27, |
244 | Complex = 28, |
245 | Bitfield = 29, |
246 | BSTR = 30, |
247 | HResult = 31, |
248 | Char16 = 32, |
249 | Char32 = 33 |
250 | }; |
251 | |
252 | /// These values correspond to the flags that can be combined to control the |
253 | /// return of an undecorated name for a C++ decorated name, and are documented |
254 | /// here: https://msdn.microsoft.com/en-us/library/kszfk0fs.aspx |
255 | enum PDB_UndnameFlags: uint32_t { |
256 | Undname_Complete = 0x0, |
257 | Undname_NoLeadingUnderscores = 0x1, |
258 | Undname_NoMsKeywords = 0x2, |
259 | Undname_NoFuncReturns = 0x4, |
260 | Undname_NoAllocModel = 0x8, |
261 | Undname_NoAllocLang = 0x10, |
262 | Undname_Reserved1 = 0x20, |
263 | Undname_Reserved2 = 0x40, |
264 | Undname_NoThisType = 0x60, |
265 | Undname_NoAccessSpec = 0x80, |
266 | Undname_NoThrowSig = 0x100, |
267 | Undname_NoMemberType = 0x200, |
268 | Undname_NoReturnUDTModel = 0x400, |
269 | Undname_32BitDecode = 0x800, |
270 | Undname_NameOnly = 0x1000, |
271 | Undname_TypeOnly = 0x2000, |
272 | Undname_HaveParams = 0x4000, |
273 | Undname_NoECSU = 0x8000, |
274 | Undname_NoIdentCharCheck = 0x10000, |
275 | Undname_NoPTR64 = 0x20000 |
276 | }; |
277 | |
278 | enum class PDB_MemberAccess { Private = 1, Protected = 2, Public = 3 }; |
279 | |
280 | struct VersionInfo { |
281 | uint32_t Major; |
282 | uint32_t Minor; |
283 | uint32_t Build; |
284 | uint32_t QFE; |
285 | }; |
286 | |
287 | enum PDB_VariantType { |
288 | Empty, |
289 | Unknown, |
290 | Int8, |
291 | Int16, |
292 | Int32, |
293 | Int64, |
294 | Single, |
295 | Double, |
296 | UInt8, |
297 | UInt16, |
298 | UInt32, |
299 | UInt64, |
300 | Bool, |
301 | String |
302 | }; |
303 | |
304 | struct Variant { |
305 | Variant() = default; |
306 | |
307 | Variant(const Variant &Other) { |
308 | *this = Other; |
309 | } |
310 | |
311 | ~Variant() { |
312 | if (Type == PDB_VariantType::String) |
313 | delete[] Value.String; |
314 | } |
315 | |
316 | PDB_VariantType Type = PDB_VariantType::Empty; |
317 | union { |
318 | bool Bool; |
319 | int8_t Int8; |
320 | int16_t Int16; |
321 | int32_t Int32; |
322 | int64_t Int64; |
323 | float Single; |
324 | double Double; |
325 | uint8_t UInt8; |
326 | uint16_t UInt16; |
327 | uint32_t UInt32; |
328 | uint64_t UInt64; |
329 | char *String; |
330 | } Value; |
331 | |
332 | #define VARIANT_EQUAL_CASE(Enum) \ |
333 | case PDB_VariantType::Enum: \ |
334 | return Value.Enum == Other.Value.Enum; |
335 | |
336 | bool operator==(const Variant &Other) const { |
337 | if (Type != Other.Type) |
338 | return false; |
339 | switch (Type) { |
340 | VARIANT_EQUAL_CASE(Bool) |
341 | VARIANT_EQUAL_CASE(Int8) |
342 | VARIANT_EQUAL_CASE(Int16) |
343 | VARIANT_EQUAL_CASE(Int32) |
344 | VARIANT_EQUAL_CASE(Int64) |
345 | VARIANT_EQUAL_CASE(Single) |
346 | VARIANT_EQUAL_CASE(Double) |
347 | VARIANT_EQUAL_CASE(UInt8) |
348 | VARIANT_EQUAL_CASE(UInt16) |
349 | VARIANT_EQUAL_CASE(UInt32) |
350 | VARIANT_EQUAL_CASE(UInt64) |
351 | VARIANT_EQUAL_CASE(String) |
352 | default: |
353 | return true; |
354 | } |
355 | } |
356 | |
357 | #undef VARIANT_EQUAL_CASE |
358 | |
359 | bool operator!=(const Variant &Other) const { return !(*this == Other); } |
360 | Variant &operator=(const Variant &Other) { |
361 | if (this == &Other) |
362 | return *this; |
363 | if (Type == PDB_VariantType::String) |
364 | delete[] Value.String; |
365 | Type = Other.Type; |
366 | Value = Other.Value; |
367 | if (Other.Type == PDB_VariantType::String && |
368 | Other.Value.String != nullptr) { |
369 | Value.String = new char[strlen(Other.Value.String) + 1]; |
370 | ::strcpy(Value.String, Other.Value.String); |
371 | } |
372 | return *this; |
373 | } |
374 | }; |
375 | |
376 | } // end namespace pdb |
377 | } // end namespace llvm |
378 | |
379 | namespace std { |
380 | |
381 | template <> struct hash<llvm::pdb::PDB_SymType> { |
382 | using argument_type = llvm::pdb::PDB_SymType; |
383 | using result_type = std::size_t; |
384 | |
385 | result_type operator()(const argument_type &Arg) const { |
386 | return std::hash<int>()(static_cast<int>(Arg)); |
387 | } |
388 | }; |
389 | |
390 | } // end namespace std |
391 | |
392 | #endif // LLVM_DEBUGINFO_PDB_PDBTYPES_H |