1 | //===- PDBTypes.h - Defines enums for various fields contained in PDB ----====// |
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 LLVM_DEBUGINFO_PDB_PDBTYPES_H |
10 | #define LLVM_DEBUGINFO_PDB_PDBTYPES_H |
11 | |
12 | #include "llvm/ADT/APFloat.h" |
13 | #include "llvm/DebugInfo/CodeView/CodeView.h" |
14 | #include "llvm/DebugInfo/PDB/IPDBEnumChildren.h" |
15 | #include "llvm/DebugInfo/PDB/IPDBFrameData.h" |
16 | #include "llvm/DebugInfo/PDB/Native/RawTypes.h" |
17 | #include <cctype> |
18 | #include <cstddef> |
19 | #include <cstdint> |
20 | #include <cstring> |
21 | #include <functional> |
22 | |
23 | namespace llvm { |
24 | namespace pdb { |
25 | |
26 | typedef uint32_t SymIndexId; |
27 | |
28 | class IPDBDataStream; |
29 | class IPDBInjectedSource; |
30 | class IPDBLineNumber; |
31 | class IPDBSectionContrib; |
32 | class IPDBSession; |
33 | class IPDBSourceFile; |
34 | class IPDBTable; |
35 | class PDBSymDumper; |
36 | class PDBSymbol; |
37 | class PDBSymbolExe; |
38 | class PDBSymbolCompiland; |
39 | class PDBSymbolCompilandDetails; |
40 | class PDBSymbolCompilandEnv; |
41 | class PDBSymbolFunc; |
42 | class PDBSymbolBlock; |
43 | class PDBSymbolData; |
44 | class PDBSymbolAnnotation; |
45 | class PDBSymbolLabel; |
46 | class PDBSymbolPublicSymbol; |
47 | class PDBSymbolTypeUDT; |
48 | class PDBSymbolTypeEnum; |
49 | class PDBSymbolTypeFunctionSig; |
50 | class PDBSymbolTypePointer; |
51 | class PDBSymbolTypeArray; |
52 | class PDBSymbolTypeBuiltin; |
53 | class PDBSymbolTypeTypedef; |
54 | class PDBSymbolTypeBaseClass; |
55 | class PDBSymbolTypeFriend; |
56 | class PDBSymbolTypeFunctionArg; |
57 | class PDBSymbolFuncDebugStart; |
58 | class PDBSymbolFuncDebugEnd; |
59 | class PDBSymbolUsingNamespace; |
60 | class PDBSymbolTypeVTableShape; |
61 | class PDBSymbolTypeVTable; |
62 | class PDBSymbolCustom; |
63 | class PDBSymbolThunk; |
64 | class PDBSymbolTypeCustom; |
65 | class PDBSymbolTypeManaged; |
66 | class PDBSymbolTypeDimension; |
67 | class PDBSymbolUnknown; |
68 | |
69 | using IPDBEnumSymbols = IPDBEnumChildren<PDBSymbol>; |
70 | using IPDBEnumSourceFiles = IPDBEnumChildren<IPDBSourceFile>; |
71 | using IPDBEnumDataStreams = IPDBEnumChildren<IPDBDataStream>; |
72 | using IPDBEnumLineNumbers = IPDBEnumChildren<IPDBLineNumber>; |
73 | using IPDBEnumTables = IPDBEnumChildren<IPDBTable>; |
74 | using IPDBEnumInjectedSources = IPDBEnumChildren<IPDBInjectedSource>; |
75 | using IPDBEnumSectionContribs = IPDBEnumChildren<IPDBSectionContrib>; |
76 | using IPDBEnumFrameData = IPDBEnumChildren<IPDBFrameData>; |
77 | |
78 | /// Specifies which PDB reader implementation is to be used. Only a value |
79 | /// of PDB_ReaderType::DIA is currently supported, but Native is in the works. |
80 | enum class PDB_ReaderType { |
81 | DIA = 0, |
82 | Native = 1, |
83 | }; |
84 | |
85 | /// An enumeration indicating the type of data contained in this table. |
86 | enum class PDB_TableType { |
87 | TableInvalid = 0, |
88 | Symbols, |
89 | SourceFiles, |
90 | LineNumbers, |
91 | SectionContribs, |
92 | Segments, |
93 | InjectedSources, |
94 | FrameData, |
95 | InputAssemblyFiles, |
96 | Dbg |
97 | }; |
98 | |
99 | /// Defines flags used for enumerating child symbols. This corresponds to the |
100 | /// NameSearchOptions enumeration which is documented here: |
101 | /// https://msdn.microsoft.com/en-us/library/yat28ads.aspx |
102 | enum PDB_NameSearchFlags { |
103 | NS_Default = 0x0, |
104 | NS_CaseSensitive = 0x1, |
105 | NS_CaseInsensitive = 0x2, |
106 | NS_FileNameExtMatch = 0x4, |
107 | NS_Regex = 0x8, |
108 | NS_UndecoratedName = 0x10, |
109 | |
110 | // For backward compatibility. |
111 | NS_CaseInFileNameExt = NS_CaseInsensitive | NS_FileNameExtMatch, |
112 | NS_CaseRegex = NS_Regex | NS_CaseSensitive, |
113 | NS_CaseInRex = NS_Regex | NS_CaseInsensitive |
114 | }; |
115 | |
116 | /// Specifies the hash algorithm that a source file from a PDB was hashed with. |
117 | /// This corresponds to the CV_SourceChksum_t enumeration and are documented |
118 | /// here: https://msdn.microsoft.com/en-us/library/e96az21x.aspx |
119 | enum class PDB_Checksum { None = 0, MD5 = 1, SHA1 = 2, SHA256 = 3 }; |
120 | |
121 | /// These values correspond to the CV_CPU_TYPE_e enumeration, and are documented |
122 | /// here: https://msdn.microsoft.com/en-us/library/b2fc64ek.aspx |
123 | using PDB_Cpu = codeview::CPUType; |
124 | |
125 | enum class PDB_Machine { |
126 | Invalid = 0xffff, |
127 | Unknown = 0x0, |
128 | Am33 = 0x13, |
129 | Amd64 = 0x8664, |
130 | Arm = 0x1C0, |
131 | Arm64 = 0xaa64, |
132 | ArmNT = 0x1C4, |
133 | Ebc = 0xEBC, |
134 | x86 = 0x14C, |
135 | Ia64 = 0x200, |
136 | M32R = 0x9041, |
137 | Mips16 = 0x266, |
138 | MipsFpu = 0x366, |
139 | MipsFpu16 = 0x466, |
140 | PowerPC = 0x1F0, |
141 | PowerPCFP = 0x1F1, |
142 | R4000 = 0x166, |
143 | SH3 = 0x1A2, |
144 | SH3DSP = 0x1A3, |
145 | SH4 = 0x1A6, |
146 | SH5 = 0x1A8, |
147 | Thumb = 0x1C2, |
148 | WceMipsV2 = 0x169 |
149 | }; |
150 | |
151 | // A struct with an inner unnamed enum with explicit underlying type resuls |
152 | // in an enum class that can implicitly convert to the underlying type, which |
153 | // is convenient for this enum. |
154 | struct PDB_SourceCompression { |
155 | enum : uint32_t { |
156 | // No compression. Produced e.g. by `link.exe /natvis:foo.natvis`. |
157 | None, |
158 | // Not known what produces this. |
159 | RunLengthEncoded, |
160 | // Not known what produces this. |
161 | Huffman, |
162 | // Not known what produces this. |
163 | LZ, |
164 | // Produced e.g. by `csc /debug`. The encoded data is its own mini-stream |
165 | // with the following layout (in little endian): |
166 | // GUID LanguageTypeGuid; |
167 | // GUID LanguageVendorGuid; |
168 | // GUID DocumentTypeGuid; |
169 | // GUID HashFunctionGuid; |
170 | // uint32_t HashDataSize; |
171 | // uint32_t CompressedDataSize; |
172 | // Followed by HashDataSize bytes containing a hash checksum, |
173 | // followed by CompressedDataSize bytes containing source contents. |
174 | // |
175 | // CompressedDataSize can be 0, in this case only the hash data is present. |
176 | // (CompressedDataSize is != 0 e.g. if `/embed` is passed to csc.exe.) |
177 | // The compressed data format is: |
178 | // uint32_t UncompressedDataSize; |
179 | // If UncompressedDataSize is 0, the data is stored uncompressed and |
180 | // CompressedDataSize stores the uncompressed size. |
181 | // If UncompressedDataSize is != 0, then the data is in raw deflate |
182 | // encoding as described in rfc1951. |
183 | // |
184 | // A GUID is 16 bytes, stored in the usual |
185 | // uint32_t |
186 | // uint16_t |
187 | // uint16_t |
188 | // uint8_t[24] |
189 | // layout. |
190 | // |
191 | // Well-known GUIDs for LanguageTypeGuid are: |
192 | // 63a08714-fc37-11d2-904c-00c04fa302a1 C |
193 | // 3a12d0b7-c26c-11d0-b442-00a0244a1dd2 C++ |
194 | // 3f5162f8-07c6-11d3-9053-00c04fa302a1 C# |
195 | // af046cd1-d0e1-11d2-977c-00a0c9b4d50c Cobol |
196 | // ab4f38c9-b6e6-43ba-be3b-58080b2ccce3 F# |
197 | // 3a12d0b4-c26c-11d0-b442-00a0244a1dd2 Java |
198 | // 3a12d0b6-c26c-11d0-b442-00a0244a1dd2 JScript |
199 | // af046cd2-d0e1-11d2-977c-00a0c9b4d50c Pascal |
200 | // 3a12d0b8-c26c-11d0-b442-00a0244a1dd2 Visual Basic |
201 | // |
202 | // Well-known GUIDs for LanguageVendorGuid are: |
203 | // 994b45c4-e6e9-11d2-903f-00c04fa302a1 Microsoft |
204 | // |
205 | // Well-known GUIDs for DocumentTypeGuid are: |
206 | // 5a869d0b-6611-11d3-bd2a-0000f80849bd Text |
207 | // |
208 | // Well-known GUIDs for HashFunctionGuid are: |
209 | // 406ea660-64cf-4c82-b6f0-42d48172a799 MD5 (HashDataSize is 16) |
210 | // ff1816ec-aa5e-4d10-87f7-6f4963833460 SHA1 (HashDataSize is 20) |
211 | // 8829d00f-11b8-4213-878b-770e8597ac16 SHA256 (HashDataSize is 32) |
212 | DotNet = 101, |
213 | }; |
214 | }; |
215 | |
216 | /// These values correspond to the CV_call_e enumeration, and are documented |
217 | /// at the following locations: |
218 | /// https://msdn.microsoft.com/en-us/library/b2fc64ek.aspx |
219 | /// https://msdn.microsoft.com/en-us/library/windows/desktop/ms680207(v=vs.85).aspx |
220 | using PDB_CallingConv = codeview::CallingConvention; |
221 | |
222 | /// These values correspond to the CV_CFL_LANG enumeration, and are documented |
223 | /// here: https://msdn.microsoft.com/en-us/library/bw3aekw6.aspx |
224 | using PDB_Lang = codeview::SourceLanguage; |
225 | |
226 | /// These values correspond to the DataKind enumeration, and are documented |
227 | /// here: https://msdn.microsoft.com/en-us/library/b2x2t313.aspx |
228 | enum class PDB_DataKind { |
229 | Unknown, |
230 | Local, |
231 | StaticLocal, |
232 | Param, |
233 | ObjectPtr, |
234 | FileStatic, |
235 | Global, |
236 | Member, |
237 | StaticMember, |
238 | Constant |
239 | }; |
240 | |
241 | /// These values correspond to the SymTagEnum enumeration, and are documented |
242 | /// here: https://msdn.microsoft.com/en-us/library/bkedss5f.aspx |
243 | enum class PDB_SymType { |
244 | None, |
245 | Exe, |
246 | Compiland, |
247 | CompilandDetails, |
248 | CompilandEnv, |
249 | Function, |
250 | Block, |
251 | Data, |
252 | Annotation, |
253 | Label, |
254 | PublicSymbol, |
255 | UDT, |
256 | Enum, |
257 | FunctionSig, |
258 | PointerType, |
259 | ArrayType, |
260 | BuiltinType, |
261 | Typedef, |
262 | BaseClass, |
263 | Friend, |
264 | FunctionArg, |
265 | FuncDebugStart, |
266 | FuncDebugEnd, |
267 | UsingNamespace, |
268 | VTableShape, |
269 | VTable, |
270 | Custom, |
271 | Thunk, |
272 | CustomType, |
273 | ManagedType, |
274 | Dimension, |
275 | CallSite, |
276 | InlineSite, |
277 | BaseInterface, |
278 | VectorType, |
279 | MatrixType, |
280 | HLSLType, |
281 | Caller, |
282 | Callee, |
283 | Export, |
284 | HeapAllocationSite, |
285 | CoffGroup, |
286 | Inlinee, |
287 | Max |
288 | }; |
289 | |
290 | /// These values correspond to the LocationType enumeration, and are documented |
291 | /// here: https://msdn.microsoft.com/en-us/library/f57kaez3.aspx |
292 | enum class PDB_LocType { |
293 | Null, |
294 | Static, |
295 | TLS, |
296 | RegRel, |
297 | ThisRel, |
298 | Enregistered, |
299 | BitField, |
300 | Slot, |
301 | IlRel, |
302 | MetaData, |
303 | Constant, |
304 | RegRelAliasIndir, |
305 | Max |
306 | }; |
307 | |
308 | /// These values correspond to the UdtKind enumeration, and are documented |
309 | /// here: https://msdn.microsoft.com/en-us/library/wcstk66t.aspx |
310 | enum class PDB_UdtType { Struct, Class, Union, Interface }; |
311 | |
312 | /// These values correspond to the StackFrameTypeEnum enumeration, and are |
313 | /// documented here: https://msdn.microsoft.com/en-us/library/bc5207xw.aspx. |
314 | enum class PDB_StackFrameType : uint16_t { |
315 | FPO, |
316 | KernelTrap, |
317 | KernelTSS, |
318 | EBP, |
319 | FrameData, |
320 | Unknown = 0xffff |
321 | }; |
322 | |
323 | /// These values correspond to the MemoryTypeEnum enumeration, and are |
324 | /// documented here: https://msdn.microsoft.com/en-us/library/ms165609.aspx. |
325 | enum class PDB_MemoryType : uint16_t { |
326 | Code, |
327 | Data, |
328 | Stack, |
329 | HeapCode, |
330 | Any = 0xffff |
331 | }; |
332 | |
333 | /// These values correspond to the Basictype enumeration, and are documented |
334 | /// here: https://msdn.microsoft.com/en-us/library/4szdtzc3.aspx |
335 | enum class PDB_BuiltinType { |
336 | None = 0, |
337 | Void = 1, |
338 | Char = 2, |
339 | WCharT = 3, |
340 | Int = 6, |
341 | UInt = 7, |
342 | Float = 8, |
343 | BCD = 9, |
344 | Bool = 10, |
345 | Long = 13, |
346 | ULong = 14, |
347 | Currency = 25, |
348 | Date = 26, |
349 | Variant = 27, |
350 | Complex = 28, |
351 | Bitfield = 29, |
352 | BSTR = 30, |
353 | HResult = 31, |
354 | Char16 = 32, |
355 | Char32 = 33, |
356 | Char8 = 34, |
357 | }; |
358 | |
359 | /// These values correspond to the flags that can be combined to control the |
360 | /// return of an undecorated name for a C++ decorated name, and are documented |
361 | /// here: https://msdn.microsoft.com/en-us/library/kszfk0fs.aspx |
362 | enum PDB_UndnameFlags : uint32_t { |
363 | Undname_Complete = 0x0, |
364 | Undname_NoLeadingUnderscores = 0x1, |
365 | Undname_NoMsKeywords = 0x2, |
366 | Undname_NoFuncReturns = 0x4, |
367 | Undname_NoAllocModel = 0x8, |
368 | Undname_NoAllocLang = 0x10, |
369 | Undname_Reserved1 = 0x20, |
370 | Undname_Reserved2 = 0x40, |
371 | Undname_NoThisType = 0x60, |
372 | Undname_NoAccessSpec = 0x80, |
373 | Undname_NoThrowSig = 0x100, |
374 | Undname_NoMemberType = 0x200, |
375 | Undname_NoReturnUDTModel = 0x400, |
376 | Undname_32BitDecode = 0x800, |
377 | Undname_NameOnly = 0x1000, |
378 | Undname_TypeOnly = 0x2000, |
379 | Undname_HaveParams = 0x4000, |
380 | Undname_NoECSU = 0x8000, |
381 | Undname_NoIdentCharCheck = 0x10000, |
382 | Undname_NoPTR64 = 0x20000 |
383 | }; |
384 | |
385 | enum class PDB_MemberAccess { Private = 1, Protected = 2, Public = 3 }; |
386 | |
387 | struct VersionInfo { |
388 | uint32_t Major; |
389 | uint32_t Minor; |
390 | uint32_t Build; |
391 | uint32_t QFE; |
392 | }; |
393 | |
394 | enum PDB_VariantType { |
395 | Empty, |
396 | Unknown, |
397 | Int8, |
398 | Int16, |
399 | Int32, |
400 | Int64, |
401 | Single, |
402 | Double, |
403 | UInt8, |
404 | UInt16, |
405 | UInt32, |
406 | UInt64, |
407 | Bool, |
408 | String |
409 | }; |
410 | |
411 | struct Variant { |
412 | Variant() = default; |
413 | |
414 | explicit Variant(bool V) : Type(PDB_VariantType::Bool) { Value.Bool = V; } |
415 | explicit Variant(int8_t V) : Type(PDB_VariantType::Int8) { Value.Int8 = V; } |
416 | explicit Variant(int16_t V) : Type(PDB_VariantType::Int16) { |
417 | Value.Int16 = V; |
418 | } |
419 | explicit Variant(int32_t V) : Type(PDB_VariantType::Int32) { |
420 | Value.Int32 = V; |
421 | } |
422 | explicit Variant(int64_t V) : Type(PDB_VariantType::Int64) { |
423 | Value.Int64 = V; |
424 | } |
425 | explicit Variant(float V) : Type(PDB_VariantType::Single) { |
426 | Value.Single = V; |
427 | } |
428 | explicit Variant(double V) : Type(PDB_VariantType::Double) { |
429 | Value.Double = V; |
430 | } |
431 | explicit Variant(uint8_t V) : Type(PDB_VariantType::UInt8) { |
432 | Value.UInt8 = V; |
433 | } |
434 | explicit Variant(uint16_t V) : Type(PDB_VariantType::UInt16) { |
435 | Value.UInt16 = V; |
436 | } |
437 | explicit Variant(uint32_t V) : Type(PDB_VariantType::UInt32) { |
438 | Value.UInt32 = V; |
439 | } |
440 | explicit Variant(uint64_t V) : Type(PDB_VariantType::UInt64) { |
441 | Value.UInt64 = V; |
442 | } |
443 | |
444 | Variant(const Variant &Other) { |
445 | *this = Other; |
446 | } |
447 | |
448 | ~Variant() { |
449 | if (Type == PDB_VariantType::String) |
450 | delete[] Value.String; |
451 | } |
452 | |
453 | PDB_VariantType Type = PDB_VariantType::Empty; |
454 | union { |
455 | bool Bool; |
456 | int8_t Int8; |
457 | int16_t Int16; |
458 | int32_t Int32; |
459 | int64_t Int64; |
460 | float Single; |
461 | double Double; |
462 | uint8_t UInt8; |
463 | uint16_t UInt16; |
464 | uint32_t UInt32; |
465 | uint64_t UInt64; |
466 | char *String; |
467 | } Value; |
468 | |
469 | bool isIntegralType() const { |
470 | switch (Type) { |
471 | case Bool: |
472 | case Int8: |
473 | case Int16: |
474 | case Int32: |
475 | case Int64: |
476 | case UInt8: |
477 | case UInt16: |
478 | case UInt32: |
479 | case UInt64: |
480 | return true; |
481 | default: |
482 | return false; |
483 | } |
484 | } |
485 | |
486 | #define VARIANT_WIDTH(Enum, NumBits) \ |
487 | case PDB_VariantType::Enum: \ |
488 | return NumBits; |
489 | |
490 | unsigned getBitWidth() const { |
491 | switch (Type) { |
492 | VARIANT_WIDTH(Bool, 1u) |
493 | VARIANT_WIDTH(Int8, 8u) |
494 | VARIANT_WIDTH(Int16, 16u) |
495 | VARIANT_WIDTH(Int32, 32u) |
496 | VARIANT_WIDTH(Int64, 64u) |
497 | VARIANT_WIDTH(Single, 32u) |
498 | VARIANT_WIDTH(Double, 64u) |
499 | VARIANT_WIDTH(UInt8, 8u) |
500 | VARIANT_WIDTH(UInt16, 16u) |
501 | VARIANT_WIDTH(UInt32, 32u) |
502 | VARIANT_WIDTH(UInt64, 64u) |
503 | default: |
504 | assert(false && "Variant::toAPSInt called on non-numeric type" ); |
505 | return 0u; |
506 | } |
507 | } |
508 | |
509 | #undef VARIANT_WIDTH |
510 | |
511 | #define VARIANT_APSINT(Enum, NumBits, IsUnsigned) \ |
512 | case PDB_VariantType::Enum: \ |
513 | return APSInt(APInt(NumBits, Value.Enum), IsUnsigned); |
514 | |
515 | APSInt toAPSInt() const { |
516 | switch (Type) { |
517 | VARIANT_APSINT(Bool, 1u, true) |
518 | VARIANT_APSINT(Int8, 8u, false) |
519 | VARIANT_APSINT(Int16, 16u, false) |
520 | VARIANT_APSINT(Int32, 32u, false) |
521 | VARIANT_APSINT(Int64, 64u, false) |
522 | VARIANT_APSINT(UInt8, 8u, true) |
523 | VARIANT_APSINT(UInt16, 16u, true) |
524 | VARIANT_APSINT(UInt32, 32u, true) |
525 | VARIANT_APSINT(UInt64, 64u, true) |
526 | default: |
527 | assert(false && "Variant::toAPSInt called on non-integral type" ); |
528 | return APSInt(); |
529 | } |
530 | } |
531 | |
532 | #undef VARIANT_APSINT |
533 | |
534 | APFloat toAPFloat() const { |
535 | // Float constants may be tagged as integers. |
536 | switch (Type) { |
537 | case PDB_VariantType::Single: |
538 | case PDB_VariantType::UInt32: |
539 | case PDB_VariantType::Int32: |
540 | return APFloat(Value.Single); |
541 | case PDB_VariantType::Double: |
542 | case PDB_VariantType::UInt64: |
543 | case PDB_VariantType::Int64: |
544 | return APFloat(Value.Double); |
545 | default: |
546 | assert(false && "Variant::toAPFloat called on non-floating-point type" ); |
547 | return APFloat::getZero(Sem: APFloat::IEEEsingle()); |
548 | } |
549 | } |
550 | |
551 | #define VARIANT_EQUAL_CASE(Enum) \ |
552 | case PDB_VariantType::Enum: \ |
553 | return Value.Enum == Other.Value.Enum; |
554 | |
555 | bool operator==(const Variant &Other) const { |
556 | if (Type != Other.Type) |
557 | return false; |
558 | switch (Type) { |
559 | VARIANT_EQUAL_CASE(Bool) |
560 | VARIANT_EQUAL_CASE(Int8) |
561 | VARIANT_EQUAL_CASE(Int16) |
562 | VARIANT_EQUAL_CASE(Int32) |
563 | VARIANT_EQUAL_CASE(Int64) |
564 | VARIANT_EQUAL_CASE(Single) |
565 | VARIANT_EQUAL_CASE(Double) |
566 | VARIANT_EQUAL_CASE(UInt8) |
567 | VARIANT_EQUAL_CASE(UInt16) |
568 | VARIANT_EQUAL_CASE(UInt32) |
569 | VARIANT_EQUAL_CASE(UInt64) |
570 | VARIANT_EQUAL_CASE(String) |
571 | default: |
572 | return true; |
573 | } |
574 | } |
575 | |
576 | #undef VARIANT_EQUAL_CASE |
577 | |
578 | bool operator!=(const Variant &Other) const { return !(*this == Other); } |
579 | Variant &operator=(const Variant &Other) { |
580 | if (this == &Other) |
581 | return *this; |
582 | if (Type == PDB_VariantType::String) |
583 | delete[] Value.String; |
584 | Type = Other.Type; |
585 | Value = Other.Value; |
586 | if (Other.Type == PDB_VariantType::String && |
587 | Other.Value.String != nullptr) { |
588 | Value.String = new char[strlen(s: Other.Value.String) + 1]; |
589 | ::strcpy(dest: Value.String, src: Other.Value.String); |
590 | } |
591 | return *this; |
592 | } |
593 | }; |
594 | |
595 | } // end namespace pdb |
596 | } // end namespace llvm |
597 | |
598 | namespace std { |
599 | |
600 | template <> struct hash<llvm::pdb::PDB_SymType> { |
601 | using argument_type = llvm::pdb::PDB_SymType; |
602 | using result_type = std::size_t; |
603 | |
604 | result_type operator()(const argument_type &Arg) const { |
605 | return std::hash<int>()(static_cast<int>(Arg)); |
606 | } |
607 | }; |
608 | |
609 | } // end namespace std |
610 | |
611 | #endif // LLVM_DEBUGINFO_PDB_PDBTYPES_H |
612 | |