10b57cec5SDimitry Andric //===- PDBTypes.h - Defines enums for various fields contained in PDB ----====//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric 
90b57cec5SDimitry Andric #ifndef LLVM_DEBUGINFO_PDB_PDBTYPES_H
100b57cec5SDimitry Andric #define LLVM_DEBUGINFO_PDB_PDBTYPES_H
110b57cec5SDimitry Andric 
125ffd83dbSDimitry Andric #include "llvm/ADT/APFloat.h"
130b57cec5SDimitry Andric #include "llvm/DebugInfo/CodeView/CodeView.h"
140b57cec5SDimitry Andric #include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"
150b57cec5SDimitry Andric #include "llvm/DebugInfo/PDB/IPDBFrameData.h"
160b57cec5SDimitry Andric #include "llvm/DebugInfo/PDB/Native/RawTypes.h"
170b57cec5SDimitry Andric #include <cctype>
180b57cec5SDimitry Andric #include <cstddef>
190b57cec5SDimitry Andric #include <cstdint>
200b57cec5SDimitry Andric #include <cstring>
210b57cec5SDimitry Andric #include <functional>
220b57cec5SDimitry Andric 
230b57cec5SDimitry Andric namespace llvm {
240b57cec5SDimitry Andric namespace pdb {
250b57cec5SDimitry Andric 
260b57cec5SDimitry Andric typedef uint32_t SymIndexId;
270b57cec5SDimitry Andric 
280b57cec5SDimitry Andric class IPDBDataStream;
290b57cec5SDimitry Andric class IPDBInjectedSource;
300b57cec5SDimitry Andric class IPDBLineNumber;
310b57cec5SDimitry Andric class IPDBSectionContrib;
325ffd83dbSDimitry Andric class IPDBSession;
330b57cec5SDimitry Andric class IPDBSourceFile;
340b57cec5SDimitry Andric class IPDBTable;
350b57cec5SDimitry Andric class PDBSymDumper;
360b57cec5SDimitry Andric class PDBSymbol;
370b57cec5SDimitry Andric class PDBSymbolExe;
380b57cec5SDimitry Andric class PDBSymbolCompiland;
390b57cec5SDimitry Andric class PDBSymbolCompilandDetails;
400b57cec5SDimitry Andric class PDBSymbolCompilandEnv;
410b57cec5SDimitry Andric class PDBSymbolFunc;
420b57cec5SDimitry Andric class PDBSymbolBlock;
430b57cec5SDimitry Andric class PDBSymbolData;
440b57cec5SDimitry Andric class PDBSymbolAnnotation;
450b57cec5SDimitry Andric class PDBSymbolLabel;
460b57cec5SDimitry Andric class PDBSymbolPublicSymbol;
470b57cec5SDimitry Andric class PDBSymbolTypeUDT;
480b57cec5SDimitry Andric class PDBSymbolTypeEnum;
490b57cec5SDimitry Andric class PDBSymbolTypeFunctionSig;
500b57cec5SDimitry Andric class PDBSymbolTypePointer;
510b57cec5SDimitry Andric class PDBSymbolTypeArray;
520b57cec5SDimitry Andric class PDBSymbolTypeBuiltin;
530b57cec5SDimitry Andric class PDBSymbolTypeTypedef;
540b57cec5SDimitry Andric class PDBSymbolTypeBaseClass;
550b57cec5SDimitry Andric class PDBSymbolTypeFriend;
560b57cec5SDimitry Andric class PDBSymbolTypeFunctionArg;
570b57cec5SDimitry Andric class PDBSymbolFuncDebugStart;
580b57cec5SDimitry Andric class PDBSymbolFuncDebugEnd;
590b57cec5SDimitry Andric class PDBSymbolUsingNamespace;
600b57cec5SDimitry Andric class PDBSymbolTypeVTableShape;
610b57cec5SDimitry Andric class PDBSymbolTypeVTable;
620b57cec5SDimitry Andric class PDBSymbolCustom;
630b57cec5SDimitry Andric class PDBSymbolThunk;
640b57cec5SDimitry Andric class PDBSymbolTypeCustom;
650b57cec5SDimitry Andric class PDBSymbolTypeManaged;
660b57cec5SDimitry Andric class PDBSymbolTypeDimension;
670b57cec5SDimitry Andric class PDBSymbolUnknown;
680b57cec5SDimitry Andric 
690b57cec5SDimitry Andric using IPDBEnumSymbols = IPDBEnumChildren<PDBSymbol>;
700b57cec5SDimitry Andric using IPDBEnumSourceFiles = IPDBEnumChildren<IPDBSourceFile>;
710b57cec5SDimitry Andric using IPDBEnumDataStreams = IPDBEnumChildren<IPDBDataStream>;
720b57cec5SDimitry Andric using IPDBEnumLineNumbers = IPDBEnumChildren<IPDBLineNumber>;
730b57cec5SDimitry Andric using IPDBEnumTables = IPDBEnumChildren<IPDBTable>;
740b57cec5SDimitry Andric using IPDBEnumInjectedSources = IPDBEnumChildren<IPDBInjectedSource>;
750b57cec5SDimitry Andric using IPDBEnumSectionContribs = IPDBEnumChildren<IPDBSectionContrib>;
760b57cec5SDimitry Andric using IPDBEnumFrameData = IPDBEnumChildren<IPDBFrameData>;
770b57cec5SDimitry Andric 
780b57cec5SDimitry Andric /// Specifies which PDB reader implementation is to be used.  Only a value
790b57cec5SDimitry Andric /// of PDB_ReaderType::DIA is currently supported, but Native is in the works.
800b57cec5SDimitry Andric enum class PDB_ReaderType {
810b57cec5SDimitry Andric   DIA = 0,
820b57cec5SDimitry Andric   Native = 1,
830b57cec5SDimitry Andric };
840b57cec5SDimitry Andric 
850b57cec5SDimitry Andric /// An enumeration indicating the type of data contained in this table.
860b57cec5SDimitry Andric enum class PDB_TableType {
870b57cec5SDimitry Andric   TableInvalid = 0,
880b57cec5SDimitry Andric   Symbols,
890b57cec5SDimitry Andric   SourceFiles,
900b57cec5SDimitry Andric   LineNumbers,
910b57cec5SDimitry Andric   SectionContribs,
920b57cec5SDimitry Andric   Segments,
930b57cec5SDimitry Andric   InjectedSources,
940b57cec5SDimitry Andric   FrameData,
950b57cec5SDimitry Andric   InputAssemblyFiles,
960b57cec5SDimitry Andric   Dbg
970b57cec5SDimitry Andric };
980b57cec5SDimitry Andric 
990b57cec5SDimitry Andric /// Defines flags used for enumerating child symbols.  This corresponds to the
1000b57cec5SDimitry Andric /// NameSearchOptions enumeration which is documented here:
1010b57cec5SDimitry Andric /// https://msdn.microsoft.com/en-us/library/yat28ads.aspx
1020b57cec5SDimitry Andric enum PDB_NameSearchFlags {
1030b57cec5SDimitry Andric   NS_Default = 0x0,
1040b57cec5SDimitry Andric   NS_CaseSensitive = 0x1,
1050b57cec5SDimitry Andric   NS_CaseInsensitive = 0x2,
1060b57cec5SDimitry Andric   NS_FileNameExtMatch = 0x4,
1070b57cec5SDimitry Andric   NS_Regex = 0x8,
1080b57cec5SDimitry Andric   NS_UndecoratedName = 0x10,
1090b57cec5SDimitry Andric 
1100b57cec5SDimitry Andric   // For backward compatibility.
1110b57cec5SDimitry Andric   NS_CaseInFileNameExt = NS_CaseInsensitive | NS_FileNameExtMatch,
1120b57cec5SDimitry Andric   NS_CaseRegex = NS_Regex | NS_CaseSensitive,
1130b57cec5SDimitry Andric   NS_CaseInRex = NS_Regex | NS_CaseInsensitive
1140b57cec5SDimitry Andric };
1150b57cec5SDimitry Andric 
1160b57cec5SDimitry Andric /// Specifies the hash algorithm that a source file from a PDB was hashed with.
1170b57cec5SDimitry Andric /// This corresponds to the CV_SourceChksum_t enumeration and are documented
1180b57cec5SDimitry Andric /// here: https://msdn.microsoft.com/en-us/library/e96az21x.aspx
1190b57cec5SDimitry Andric enum class PDB_Checksum { None = 0, MD5 = 1, SHA1 = 2, SHA256 = 3 };
1200b57cec5SDimitry Andric 
1210b57cec5SDimitry Andric /// These values correspond to the CV_CPU_TYPE_e enumeration, and are documented
1220b57cec5SDimitry Andric /// here: https://msdn.microsoft.com/en-us/library/b2fc64ek.aspx
1230b57cec5SDimitry Andric using PDB_Cpu = codeview::CPUType;
1240b57cec5SDimitry Andric 
1250b57cec5SDimitry Andric enum class PDB_Machine {
1260b57cec5SDimitry Andric   Invalid = 0xffff,
1270b57cec5SDimitry Andric   Unknown = 0x0,
1280b57cec5SDimitry Andric   Am33 = 0x13,
1290b57cec5SDimitry Andric   Amd64 = 0x8664,
1300b57cec5SDimitry Andric   Arm = 0x1C0,
1310b57cec5SDimitry Andric   Arm64 = 0xaa64,
1320b57cec5SDimitry Andric   ArmNT = 0x1C4,
1330b57cec5SDimitry Andric   Ebc = 0xEBC,
1340b57cec5SDimitry Andric   x86 = 0x14C,
1350b57cec5SDimitry Andric   Ia64 = 0x200,
1360b57cec5SDimitry Andric   M32R = 0x9041,
1370b57cec5SDimitry Andric   Mips16 = 0x266,
1380b57cec5SDimitry Andric   MipsFpu = 0x366,
1390b57cec5SDimitry Andric   MipsFpu16 = 0x466,
1400b57cec5SDimitry Andric   PowerPC = 0x1F0,
1410b57cec5SDimitry Andric   PowerPCFP = 0x1F1,
1420b57cec5SDimitry Andric   R4000 = 0x166,
1430b57cec5SDimitry Andric   SH3 = 0x1A2,
1440b57cec5SDimitry Andric   SH3DSP = 0x1A3,
1450b57cec5SDimitry Andric   SH4 = 0x1A6,
1460b57cec5SDimitry Andric   SH5 = 0x1A8,
1470b57cec5SDimitry Andric   Thumb = 0x1C2,
1480b57cec5SDimitry Andric   WceMipsV2 = 0x169
1490b57cec5SDimitry Andric };
1500b57cec5SDimitry Andric 
1510b57cec5SDimitry Andric // A struct with an inner unnamed enum with explicit underlying type resuls
1520b57cec5SDimitry Andric // in an enum class that can implicitly convert to the underlying type, which
1530b57cec5SDimitry Andric // is convenient for this enum.
1540b57cec5SDimitry Andric struct PDB_SourceCompression {
1550b57cec5SDimitry Andric   enum : uint32_t {
1560b57cec5SDimitry Andric     // No compression. Produced e.g. by `link.exe /natvis:foo.natvis`.
1570b57cec5SDimitry Andric     None,
1580b57cec5SDimitry Andric     // Not known what produces this.
1590b57cec5SDimitry Andric     RunLengthEncoded,
1600b57cec5SDimitry Andric     // Not known what produces this.
1610b57cec5SDimitry Andric     Huffman,
1620b57cec5SDimitry Andric     // Not known what produces this.
1630b57cec5SDimitry Andric     LZ,
1640b57cec5SDimitry Andric     // Produced e.g. by `csc /debug`. The encoded data is its own mini-stream
1650b57cec5SDimitry Andric     // with the following layout (in little endian):
1660b57cec5SDimitry Andric     //   GUID LanguageTypeGuid;
1670b57cec5SDimitry Andric     //   GUID LanguageVendorGuid;
1680b57cec5SDimitry Andric     //   GUID DocumentTypeGuid;
1690b57cec5SDimitry Andric     //   GUID HashFunctionGuid;
1700b57cec5SDimitry Andric     //   uint32_t HashDataSize;
1710b57cec5SDimitry Andric     //   uint32_t CompressedDataSize;
1720b57cec5SDimitry Andric     // Followed by HashDataSize bytes containing a hash checksum,
1730b57cec5SDimitry Andric     // followed by CompressedDataSize bytes containing source contents.
1740b57cec5SDimitry Andric     //
1750b57cec5SDimitry Andric     // CompressedDataSize can be 0, in this case only the hash data is present.
1760b57cec5SDimitry Andric     // (CompressedDataSize is != 0 e.g. if `/embed` is passed to csc.exe.)
1770b57cec5SDimitry Andric     // The compressed data format is:
1780b57cec5SDimitry Andric     //   uint32_t UncompressedDataSize;
1790b57cec5SDimitry Andric     // If UncompressedDataSize is 0, the data is stored uncompressed and
1800b57cec5SDimitry Andric     // CompressedDataSize stores the uncompressed size.
1810b57cec5SDimitry Andric     // If UncompressedDataSize is != 0, then the data is in raw deflate
1820b57cec5SDimitry Andric     // encoding as described in rfc1951.
1830b57cec5SDimitry Andric     //
1840b57cec5SDimitry Andric     // A GUID is 16 bytes, stored in the usual
1850b57cec5SDimitry Andric     //   uint32_t
1860b57cec5SDimitry Andric     //   uint16_t
1870b57cec5SDimitry Andric     //   uint16_t
1880b57cec5SDimitry Andric     //   uint8_t[24]
1890b57cec5SDimitry Andric     // layout.
1900b57cec5SDimitry Andric     //
1910b57cec5SDimitry Andric     // Well-known GUIDs for LanguageTypeGuid are:
1920b57cec5SDimitry Andric     //   63a08714-fc37-11d2-904c-00c04fa302a1 C
1930b57cec5SDimitry Andric     //   3a12d0b7-c26c-11d0-b442-00a0244a1dd2 C++
1940b57cec5SDimitry Andric     //   3f5162f8-07c6-11d3-9053-00c04fa302a1 C#
1950b57cec5SDimitry Andric     //   af046cd1-d0e1-11d2-977c-00a0c9b4d50c Cobol
1960b57cec5SDimitry Andric     //   ab4f38c9-b6e6-43ba-be3b-58080b2ccce3 F#
1970b57cec5SDimitry Andric     //   3a12d0b4-c26c-11d0-b442-00a0244a1dd2 Java
1980b57cec5SDimitry Andric     //   3a12d0b6-c26c-11d0-b442-00a0244a1dd2 JScript
1990b57cec5SDimitry Andric     //   af046cd2-d0e1-11d2-977c-00a0c9b4d50c Pascal
2000b57cec5SDimitry Andric     //   3a12d0b8-c26c-11d0-b442-00a0244a1dd2 Visual Basic
2010b57cec5SDimitry Andric     //
2020b57cec5SDimitry Andric     // Well-known GUIDs for LanguageVendorGuid are:
2030b57cec5SDimitry Andric     //   994b45c4-e6e9-11d2-903f-00c04fa302a1 Microsoft
2040b57cec5SDimitry Andric     //
2050b57cec5SDimitry Andric     // Well-known GUIDs for DocumentTypeGuid are:
2060b57cec5SDimitry Andric     //   5a869d0b-6611-11d3-bd2a-0000f80849bd Text
2070b57cec5SDimitry Andric     //
2080b57cec5SDimitry Andric     // Well-known GUIDs for HashFunctionGuid are:
2090b57cec5SDimitry Andric     //   406ea660-64cf-4c82-b6f0-42d48172a799 MD5    (HashDataSize is 16)
2100b57cec5SDimitry Andric     //   ff1816ec-aa5e-4d10-87f7-6f4963833460 SHA1   (HashDataSize is 20)
2110b57cec5SDimitry Andric     //   8829d00f-11b8-4213-878b-770e8597ac16 SHA256 (HashDataSize is 32)
2120b57cec5SDimitry Andric     DotNet = 101,
2130b57cec5SDimitry Andric   };
2140b57cec5SDimitry Andric };
2150b57cec5SDimitry Andric 
2160b57cec5SDimitry Andric /// These values correspond to the CV_call_e enumeration, and are documented
2170b57cec5SDimitry Andric /// at the following locations:
2180b57cec5SDimitry Andric ///   https://msdn.microsoft.com/en-us/library/b2fc64ek.aspx
2190b57cec5SDimitry Andric ///   https://msdn.microsoft.com/en-us/library/windows/desktop/ms680207(v=vs.85).aspx
2200b57cec5SDimitry Andric using PDB_CallingConv = codeview::CallingConvention;
2210b57cec5SDimitry Andric 
2220b57cec5SDimitry Andric /// These values correspond to the CV_CFL_LANG enumeration, and are documented
2230b57cec5SDimitry Andric /// here: https://msdn.microsoft.com/en-us/library/bw3aekw6.aspx
2240b57cec5SDimitry Andric using PDB_Lang = codeview::SourceLanguage;
2250b57cec5SDimitry Andric 
2260b57cec5SDimitry Andric /// These values correspond to the DataKind enumeration, and are documented
2270b57cec5SDimitry Andric /// here: https://msdn.microsoft.com/en-us/library/b2x2t313.aspx
2280b57cec5SDimitry Andric enum class PDB_DataKind {
2290b57cec5SDimitry Andric   Unknown,
2300b57cec5SDimitry Andric   Local,
2310b57cec5SDimitry Andric   StaticLocal,
2320b57cec5SDimitry Andric   Param,
2330b57cec5SDimitry Andric   ObjectPtr,
2340b57cec5SDimitry Andric   FileStatic,
2350b57cec5SDimitry Andric   Global,
2360b57cec5SDimitry Andric   Member,
2370b57cec5SDimitry Andric   StaticMember,
2380b57cec5SDimitry Andric   Constant
2390b57cec5SDimitry Andric };
2400b57cec5SDimitry Andric 
2410b57cec5SDimitry Andric /// These values correspond to the SymTagEnum enumeration, and are documented
2420b57cec5SDimitry Andric /// here: https://msdn.microsoft.com/en-us/library/bkedss5f.aspx
2430b57cec5SDimitry Andric enum class PDB_SymType {
2440b57cec5SDimitry Andric   None,
2450b57cec5SDimitry Andric   Exe,
2460b57cec5SDimitry Andric   Compiland,
2470b57cec5SDimitry Andric   CompilandDetails,
2480b57cec5SDimitry Andric   CompilandEnv,
2490b57cec5SDimitry Andric   Function,
2500b57cec5SDimitry Andric   Block,
2510b57cec5SDimitry Andric   Data,
2520b57cec5SDimitry Andric   Annotation,
2530b57cec5SDimitry Andric   Label,
2540b57cec5SDimitry Andric   PublicSymbol,
2550b57cec5SDimitry Andric   UDT,
2560b57cec5SDimitry Andric   Enum,
2570b57cec5SDimitry Andric   FunctionSig,
2580b57cec5SDimitry Andric   PointerType,
2590b57cec5SDimitry Andric   ArrayType,
2600b57cec5SDimitry Andric   BuiltinType,
2610b57cec5SDimitry Andric   Typedef,
2620b57cec5SDimitry Andric   BaseClass,
2630b57cec5SDimitry Andric   Friend,
2640b57cec5SDimitry Andric   FunctionArg,
2650b57cec5SDimitry Andric   FuncDebugStart,
2660b57cec5SDimitry Andric   FuncDebugEnd,
2670b57cec5SDimitry Andric   UsingNamespace,
2680b57cec5SDimitry Andric   VTableShape,
2690b57cec5SDimitry Andric   VTable,
2700b57cec5SDimitry Andric   Custom,
2710b57cec5SDimitry Andric   Thunk,
2720b57cec5SDimitry Andric   CustomType,
2730b57cec5SDimitry Andric   ManagedType,
2740b57cec5SDimitry Andric   Dimension,
2750b57cec5SDimitry Andric   CallSite,
2760b57cec5SDimitry Andric   InlineSite,
2770b57cec5SDimitry Andric   BaseInterface,
2780b57cec5SDimitry Andric   VectorType,
2790b57cec5SDimitry Andric   MatrixType,
2800b57cec5SDimitry Andric   HLSLType,
2810b57cec5SDimitry Andric   Caller,
2820b57cec5SDimitry Andric   Callee,
2830b57cec5SDimitry Andric   Export,
2840b57cec5SDimitry Andric   HeapAllocationSite,
2850b57cec5SDimitry Andric   CoffGroup,
2860b57cec5SDimitry Andric   Inlinee,
2870b57cec5SDimitry Andric   Max
2880b57cec5SDimitry Andric };
2890b57cec5SDimitry Andric 
2900b57cec5SDimitry Andric /// These values correspond to the LocationType enumeration, and are documented
2910b57cec5SDimitry Andric /// here: https://msdn.microsoft.com/en-us/library/f57kaez3.aspx
2920b57cec5SDimitry Andric enum class PDB_LocType {
2930b57cec5SDimitry Andric   Null,
2940b57cec5SDimitry Andric   Static,
2950b57cec5SDimitry Andric   TLS,
2960b57cec5SDimitry Andric   RegRel,
2970b57cec5SDimitry Andric   ThisRel,
2980b57cec5SDimitry Andric   Enregistered,
2990b57cec5SDimitry Andric   BitField,
3000b57cec5SDimitry Andric   Slot,
3010b57cec5SDimitry Andric   IlRel,
3020b57cec5SDimitry Andric   MetaData,
3030b57cec5SDimitry Andric   Constant,
3040b57cec5SDimitry Andric   RegRelAliasIndir,
3050b57cec5SDimitry Andric   Max
3060b57cec5SDimitry Andric };
3070b57cec5SDimitry Andric 
3080b57cec5SDimitry Andric /// These values correspond to the UdtKind enumeration, and are documented
3090b57cec5SDimitry Andric /// here: https://msdn.microsoft.com/en-us/library/wcstk66t.aspx
3100b57cec5SDimitry Andric enum class PDB_UdtType { Struct, Class, Union, Interface };
3110b57cec5SDimitry Andric 
3120b57cec5SDimitry Andric /// These values correspond to the StackFrameTypeEnum enumeration, and are
3130b57cec5SDimitry Andric /// documented here: https://msdn.microsoft.com/en-us/library/bc5207xw.aspx.
3140b57cec5SDimitry Andric enum class PDB_StackFrameType : uint16_t {
3150b57cec5SDimitry Andric   FPO,
3160b57cec5SDimitry Andric   KernelTrap,
3170b57cec5SDimitry Andric   KernelTSS,
3180b57cec5SDimitry Andric   EBP,
3190b57cec5SDimitry Andric   FrameData,
3200b57cec5SDimitry Andric   Unknown = 0xffff
3210b57cec5SDimitry Andric };
3220b57cec5SDimitry Andric 
3230b57cec5SDimitry Andric /// These values correspond to the MemoryTypeEnum enumeration, and are
3240b57cec5SDimitry Andric /// documented here: https://msdn.microsoft.com/en-us/library/ms165609.aspx.
3250b57cec5SDimitry Andric enum class PDB_MemoryType : uint16_t {
3260b57cec5SDimitry Andric   Code,
3270b57cec5SDimitry Andric   Data,
3280b57cec5SDimitry Andric   Stack,
3290b57cec5SDimitry Andric   HeapCode,
3300b57cec5SDimitry Andric   Any = 0xffff
3310b57cec5SDimitry Andric };
3320b57cec5SDimitry Andric 
3330b57cec5SDimitry Andric /// These values correspond to the Basictype enumeration, and are documented
3340b57cec5SDimitry Andric /// here: https://msdn.microsoft.com/en-us/library/4szdtzc3.aspx
3350b57cec5SDimitry Andric enum class PDB_BuiltinType {
3360b57cec5SDimitry Andric   None = 0,
3370b57cec5SDimitry Andric   Void = 1,
3380b57cec5SDimitry Andric   Char = 2,
3390b57cec5SDimitry Andric   WCharT = 3,
3400b57cec5SDimitry Andric   Int = 6,
3410b57cec5SDimitry Andric   UInt = 7,
3420b57cec5SDimitry Andric   Float = 8,
3430b57cec5SDimitry Andric   BCD = 9,
3440b57cec5SDimitry Andric   Bool = 10,
3450b57cec5SDimitry Andric   Long = 13,
3460b57cec5SDimitry Andric   ULong = 14,
3470b57cec5SDimitry Andric   Currency = 25,
3480b57cec5SDimitry Andric   Date = 26,
3490b57cec5SDimitry Andric   Variant = 27,
3500b57cec5SDimitry Andric   Complex = 28,
3510b57cec5SDimitry Andric   Bitfield = 29,
3520b57cec5SDimitry Andric   BSTR = 30,
3530b57cec5SDimitry Andric   HResult = 31,
3540b57cec5SDimitry Andric   Char16 = 32,
35581ad6265SDimitry Andric   Char32 = 33,
35681ad6265SDimitry Andric   Char8 = 34,
3570b57cec5SDimitry Andric };
3580b57cec5SDimitry Andric 
3590b57cec5SDimitry Andric /// These values correspond to the flags that can be combined to control the
3600b57cec5SDimitry Andric /// return of an undecorated name for a C++ decorated name, and are documented
3610b57cec5SDimitry Andric /// here: https://msdn.microsoft.com/en-us/library/kszfk0fs.aspx
3620b57cec5SDimitry Andric enum PDB_UndnameFlags : uint32_t {
3630b57cec5SDimitry Andric   Undname_Complete = 0x0,
3640b57cec5SDimitry Andric   Undname_NoLeadingUnderscores = 0x1,
3650b57cec5SDimitry Andric   Undname_NoMsKeywords = 0x2,
3660b57cec5SDimitry Andric   Undname_NoFuncReturns = 0x4,
3670b57cec5SDimitry Andric   Undname_NoAllocModel = 0x8,
3680b57cec5SDimitry Andric   Undname_NoAllocLang = 0x10,
3690b57cec5SDimitry Andric   Undname_Reserved1 = 0x20,
3700b57cec5SDimitry Andric   Undname_Reserved2 = 0x40,
3710b57cec5SDimitry Andric   Undname_NoThisType = 0x60,
3720b57cec5SDimitry Andric   Undname_NoAccessSpec = 0x80,
3730b57cec5SDimitry Andric   Undname_NoThrowSig = 0x100,
3740b57cec5SDimitry Andric   Undname_NoMemberType = 0x200,
3750b57cec5SDimitry Andric   Undname_NoReturnUDTModel = 0x400,
3760b57cec5SDimitry Andric   Undname_32BitDecode = 0x800,
3770b57cec5SDimitry Andric   Undname_NameOnly = 0x1000,
3780b57cec5SDimitry Andric   Undname_TypeOnly = 0x2000,
3790b57cec5SDimitry Andric   Undname_HaveParams = 0x4000,
3800b57cec5SDimitry Andric   Undname_NoECSU = 0x8000,
3810b57cec5SDimitry Andric   Undname_NoIdentCharCheck = 0x10000,
3820b57cec5SDimitry Andric   Undname_NoPTR64 = 0x20000
3830b57cec5SDimitry Andric };
3840b57cec5SDimitry Andric 
3850b57cec5SDimitry Andric enum class PDB_MemberAccess { Private = 1, Protected = 2, Public = 3 };
3860b57cec5SDimitry Andric 
3870b57cec5SDimitry Andric struct VersionInfo {
3880b57cec5SDimitry Andric   uint32_t Major;
3890b57cec5SDimitry Andric   uint32_t Minor;
3900b57cec5SDimitry Andric   uint32_t Build;
3910b57cec5SDimitry Andric   uint32_t QFE;
3920b57cec5SDimitry Andric };
3930b57cec5SDimitry Andric 
3940b57cec5SDimitry Andric enum PDB_VariantType {
3950b57cec5SDimitry Andric   Empty,
3960b57cec5SDimitry Andric   Unknown,
3970b57cec5SDimitry Andric   Int8,
3980b57cec5SDimitry Andric   Int16,
3990b57cec5SDimitry Andric   Int32,
4000b57cec5SDimitry Andric   Int64,
4010b57cec5SDimitry Andric   Single,
4020b57cec5SDimitry Andric   Double,
4030b57cec5SDimitry Andric   UInt8,
4040b57cec5SDimitry Andric   UInt16,
4050b57cec5SDimitry Andric   UInt32,
4060b57cec5SDimitry Andric   UInt64,
4070b57cec5SDimitry Andric   Bool,
4080b57cec5SDimitry Andric   String
4090b57cec5SDimitry Andric };
4100b57cec5SDimitry Andric 
4110b57cec5SDimitry Andric struct Variant {
4120b57cec5SDimitry Andric   Variant() = default;
4130b57cec5SDimitry Andric 
VariantVariant4140b57cec5SDimitry Andric   explicit Variant(bool V) : Type(PDB_VariantType::Bool) { Value.Bool = V; }
VariantVariant4150b57cec5SDimitry Andric   explicit Variant(int8_t V) : Type(PDB_VariantType::Int8) { Value.Int8 = V; }
VariantVariant4160b57cec5SDimitry Andric   explicit Variant(int16_t V) : Type(PDB_VariantType::Int16) {
4170b57cec5SDimitry Andric     Value.Int16 = V;
4180b57cec5SDimitry Andric   }
VariantVariant4190b57cec5SDimitry Andric   explicit Variant(int32_t V) : Type(PDB_VariantType::Int32) {
4200b57cec5SDimitry Andric     Value.Int32 = V;
4210b57cec5SDimitry Andric   }
VariantVariant4220b57cec5SDimitry Andric   explicit Variant(int64_t V) : Type(PDB_VariantType::Int64) {
4230b57cec5SDimitry Andric     Value.Int64 = V;
4240b57cec5SDimitry Andric   }
VariantVariant4250b57cec5SDimitry Andric   explicit Variant(float V) : Type(PDB_VariantType::Single) {
4260b57cec5SDimitry Andric     Value.Single = V;
4270b57cec5SDimitry Andric   }
VariantVariant4280b57cec5SDimitry Andric   explicit Variant(double V) : Type(PDB_VariantType::Double) {
4290b57cec5SDimitry Andric     Value.Double = V;
4300b57cec5SDimitry Andric   }
VariantVariant4310b57cec5SDimitry Andric   explicit Variant(uint8_t V) : Type(PDB_VariantType::UInt8) {
4320b57cec5SDimitry Andric     Value.UInt8 = V;
4330b57cec5SDimitry Andric   }
VariantVariant4340b57cec5SDimitry Andric   explicit Variant(uint16_t V) : Type(PDB_VariantType::UInt16) {
4350b57cec5SDimitry Andric     Value.UInt16 = V;
4360b57cec5SDimitry Andric   }
VariantVariant4370b57cec5SDimitry Andric   explicit Variant(uint32_t V) : Type(PDB_VariantType::UInt32) {
4380b57cec5SDimitry Andric     Value.UInt32 = V;
4390b57cec5SDimitry Andric   }
VariantVariant4400b57cec5SDimitry Andric   explicit Variant(uint64_t V) : Type(PDB_VariantType::UInt64) {
4410b57cec5SDimitry Andric     Value.UInt64 = V;
4420b57cec5SDimitry Andric   }
4430b57cec5SDimitry Andric 
VariantVariant4440b57cec5SDimitry Andric   Variant(const Variant &Other) {
4450b57cec5SDimitry Andric     *this = Other;
4460b57cec5SDimitry Andric   }
4470b57cec5SDimitry Andric 
~VariantVariant4480b57cec5SDimitry Andric   ~Variant() {
4490b57cec5SDimitry Andric     if (Type == PDB_VariantType::String)
4500b57cec5SDimitry Andric       delete[] Value.String;
4510b57cec5SDimitry Andric   }
4520b57cec5SDimitry Andric 
4530b57cec5SDimitry Andric   PDB_VariantType Type = PDB_VariantType::Empty;
4540b57cec5SDimitry Andric   union {
4550b57cec5SDimitry Andric     bool Bool;
4560b57cec5SDimitry Andric     int8_t Int8;
4570b57cec5SDimitry Andric     int16_t Int16;
4580b57cec5SDimitry Andric     int32_t Int32;
4590b57cec5SDimitry Andric     int64_t Int64;
4600b57cec5SDimitry Andric     float Single;
4610b57cec5SDimitry Andric     double Double;
4620b57cec5SDimitry Andric     uint8_t UInt8;
4630b57cec5SDimitry Andric     uint16_t UInt16;
4640b57cec5SDimitry Andric     uint32_t UInt32;
4650b57cec5SDimitry Andric     uint64_t UInt64;
4660b57cec5SDimitry Andric     char *String;
4670b57cec5SDimitry Andric   } Value;
4680b57cec5SDimitry Andric 
isIntegralTypeVariant4695ffd83dbSDimitry Andric   bool isIntegralType() const {
4705ffd83dbSDimitry Andric     switch (Type) {
4715ffd83dbSDimitry Andric     case Bool:
4725ffd83dbSDimitry Andric     case Int8:
4735ffd83dbSDimitry Andric     case Int16:
4745ffd83dbSDimitry Andric     case Int32:
4755ffd83dbSDimitry Andric     case Int64:
4765ffd83dbSDimitry Andric     case UInt8:
4775ffd83dbSDimitry Andric     case UInt16:
4785ffd83dbSDimitry Andric     case UInt32:
4795ffd83dbSDimitry Andric     case UInt64:
4805ffd83dbSDimitry Andric       return true;
4815ffd83dbSDimitry Andric     default:
4825ffd83dbSDimitry Andric       return false;
4835ffd83dbSDimitry Andric     }
4845ffd83dbSDimitry Andric   }
4855ffd83dbSDimitry Andric 
4865ffd83dbSDimitry Andric #define VARIANT_WIDTH(Enum, NumBits)                                           \
4875ffd83dbSDimitry Andric   case PDB_VariantType::Enum:                                                  \
4885ffd83dbSDimitry Andric     return NumBits;
4895ffd83dbSDimitry Andric 
getBitWidthVariant4905ffd83dbSDimitry Andric   unsigned getBitWidth() const {
4915ffd83dbSDimitry Andric     switch (Type) {
4925ffd83dbSDimitry Andric       VARIANT_WIDTH(Bool, 1u)
4935ffd83dbSDimitry Andric       VARIANT_WIDTH(Int8, 8u)
4945ffd83dbSDimitry Andric       VARIANT_WIDTH(Int16, 16u)
4955ffd83dbSDimitry Andric       VARIANT_WIDTH(Int32, 32u)
4965ffd83dbSDimitry Andric       VARIANT_WIDTH(Int64, 64u)
4975ffd83dbSDimitry Andric       VARIANT_WIDTH(Single, 32u)
4985ffd83dbSDimitry Andric       VARIANT_WIDTH(Double, 64u)
4995ffd83dbSDimitry Andric       VARIANT_WIDTH(UInt8, 8u)
5005ffd83dbSDimitry Andric       VARIANT_WIDTH(UInt16, 16u)
5015ffd83dbSDimitry Andric       VARIANT_WIDTH(UInt32, 32u)
5025ffd83dbSDimitry Andric       VARIANT_WIDTH(UInt64, 64u)
5035ffd83dbSDimitry Andric     default:
5045ffd83dbSDimitry Andric       assert(false && "Variant::toAPSInt called on non-numeric type");
5055ffd83dbSDimitry Andric       return 0u;
5065ffd83dbSDimitry Andric     }
5075ffd83dbSDimitry Andric   }
5085ffd83dbSDimitry Andric 
5095ffd83dbSDimitry Andric #undef VARIANT_WIDTH
5105ffd83dbSDimitry Andric 
5115ffd83dbSDimitry Andric #define VARIANT_APSINT(Enum, NumBits, IsUnsigned)                              \
5125ffd83dbSDimitry Andric   case PDB_VariantType::Enum:                                                  \
5135ffd83dbSDimitry Andric     return APSInt(APInt(NumBits, Value.Enum), IsUnsigned);
5145ffd83dbSDimitry Andric 
toAPSIntVariant5155ffd83dbSDimitry Andric   APSInt toAPSInt() const {
5165ffd83dbSDimitry Andric     switch (Type) {
5175ffd83dbSDimitry Andric       VARIANT_APSINT(Bool, 1u, true)
5185ffd83dbSDimitry Andric       VARIANT_APSINT(Int8, 8u, false)
5195ffd83dbSDimitry Andric       VARIANT_APSINT(Int16, 16u, false)
5205ffd83dbSDimitry Andric       VARIANT_APSINT(Int32, 32u, false)
5215ffd83dbSDimitry Andric       VARIANT_APSINT(Int64, 64u, false)
5225ffd83dbSDimitry Andric       VARIANT_APSINT(UInt8, 8u, true)
5235ffd83dbSDimitry Andric       VARIANT_APSINT(UInt16, 16u, true)
5245ffd83dbSDimitry Andric       VARIANT_APSINT(UInt32, 32u, true)
5255ffd83dbSDimitry Andric       VARIANT_APSINT(UInt64, 64u, true)
5265ffd83dbSDimitry Andric     default:
5275ffd83dbSDimitry Andric       assert(false && "Variant::toAPSInt called on non-integral type");
5285ffd83dbSDimitry Andric       return APSInt();
5295ffd83dbSDimitry Andric     }
5305ffd83dbSDimitry Andric   }
5315ffd83dbSDimitry Andric 
5325ffd83dbSDimitry Andric #undef VARIANT_APSINT
5335ffd83dbSDimitry Andric 
toAPFloatVariant5345ffd83dbSDimitry Andric   APFloat toAPFloat() const {
5355ffd83dbSDimitry Andric     // Float constants may be tagged as integers.
5365ffd83dbSDimitry Andric     switch (Type) {
5375ffd83dbSDimitry Andric     case PDB_VariantType::Single:
5385ffd83dbSDimitry Andric     case PDB_VariantType::UInt32:
5395ffd83dbSDimitry Andric     case PDB_VariantType::Int32:
5405ffd83dbSDimitry Andric       return APFloat(Value.Single);
5415ffd83dbSDimitry Andric     case PDB_VariantType::Double:
5425ffd83dbSDimitry Andric     case PDB_VariantType::UInt64:
5435ffd83dbSDimitry Andric     case PDB_VariantType::Int64:
5445ffd83dbSDimitry Andric       return APFloat(Value.Double);
5455ffd83dbSDimitry Andric     default:
5465ffd83dbSDimitry Andric       assert(false && "Variant::toAPFloat called on non-floating-point type");
5475ffd83dbSDimitry Andric       return APFloat::getZero(APFloat::IEEEsingle());
5485ffd83dbSDimitry Andric     }
5495ffd83dbSDimitry Andric   }
5505ffd83dbSDimitry Andric 
5510b57cec5SDimitry Andric #define VARIANT_EQUAL_CASE(Enum)                                               \
5520b57cec5SDimitry Andric   case PDB_VariantType::Enum:                                                  \
5530b57cec5SDimitry Andric     return Value.Enum == Other.Value.Enum;
5540b57cec5SDimitry Andric 
5550b57cec5SDimitry Andric   bool operator==(const Variant &Other) const {
5560b57cec5SDimitry Andric     if (Type != Other.Type)
5570b57cec5SDimitry Andric       return false;
5580b57cec5SDimitry Andric     switch (Type) {
5590b57cec5SDimitry Andric       VARIANT_EQUAL_CASE(Bool)
5600b57cec5SDimitry Andric       VARIANT_EQUAL_CASE(Int8)
5610b57cec5SDimitry Andric       VARIANT_EQUAL_CASE(Int16)
5620b57cec5SDimitry Andric       VARIANT_EQUAL_CASE(Int32)
5630b57cec5SDimitry Andric       VARIANT_EQUAL_CASE(Int64)
5640b57cec5SDimitry Andric       VARIANT_EQUAL_CASE(Single)
5650b57cec5SDimitry Andric       VARIANT_EQUAL_CASE(Double)
5660b57cec5SDimitry Andric       VARIANT_EQUAL_CASE(UInt8)
5670b57cec5SDimitry Andric       VARIANT_EQUAL_CASE(UInt16)
5680b57cec5SDimitry Andric       VARIANT_EQUAL_CASE(UInt32)
5690b57cec5SDimitry Andric       VARIANT_EQUAL_CASE(UInt64)
5700b57cec5SDimitry Andric       VARIANT_EQUAL_CASE(String)
5710b57cec5SDimitry Andric     default:
5720b57cec5SDimitry Andric       return true;
5730b57cec5SDimitry Andric     }
5740b57cec5SDimitry Andric   }
5750b57cec5SDimitry Andric 
5760b57cec5SDimitry Andric #undef VARIANT_EQUAL_CASE
5770b57cec5SDimitry Andric 
5780b57cec5SDimitry Andric   bool operator!=(const Variant &Other) const { return !(*this == Other); }
5790b57cec5SDimitry Andric   Variant &operator=(const Variant &Other) {
5800b57cec5SDimitry Andric     if (this == &Other)
5810b57cec5SDimitry Andric       return *this;
5820b57cec5SDimitry Andric     if (Type == PDB_VariantType::String)
5830b57cec5SDimitry Andric       delete[] Value.String;
5840b57cec5SDimitry Andric     Type = Other.Type;
5850b57cec5SDimitry Andric     Value = Other.Value;
5860b57cec5SDimitry Andric     if (Other.Type == PDB_VariantType::String &&
5870b57cec5SDimitry Andric         Other.Value.String != nullptr) {
5880b57cec5SDimitry Andric       Value.String = new char[strlen(Other.Value.String) + 1];
5890b57cec5SDimitry Andric       ::strcpy(Value.String, Other.Value.String);
5900b57cec5SDimitry Andric     }
5910b57cec5SDimitry Andric     return *this;
5920b57cec5SDimitry Andric   }
5930b57cec5SDimitry Andric };
5940b57cec5SDimitry Andric 
5950b57cec5SDimitry Andric } // end namespace pdb
5960b57cec5SDimitry Andric } // end namespace llvm
5970b57cec5SDimitry Andric 
5980b57cec5SDimitry Andric namespace std {
5990b57cec5SDimitry Andric 
6000b57cec5SDimitry Andric template <> struct hash<llvm::pdb::PDB_SymType> {
6010b57cec5SDimitry Andric   using argument_type = llvm::pdb::PDB_SymType;
6020b57cec5SDimitry Andric   using result_type = std::size_t;
6030b57cec5SDimitry Andric 
6040b57cec5SDimitry Andric   result_type operator()(const argument_type &Arg) const {
6050b57cec5SDimitry Andric     return std::hash<int>()(static_cast<int>(Arg));
6060b57cec5SDimitry Andric   }
6070b57cec5SDimitry Andric };
6080b57cec5SDimitry Andric 
6090b57cec5SDimitry Andric } // end namespace std
6100b57cec5SDimitry Andric 
6110b57cec5SDimitry Andric #endif // LLVM_DEBUGINFO_PDB_PDBTYPES_H
612