1 //===-- PdbSymUid.h ---------------------------------------------*- 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 // A unique identification scheme for Pdb records.
10 // The scheme is to partition a 64-bit integer into an 8-bit tag field, which
11 // will contain some value from the PDB_SymType enumeration.  The format of the
12 // other 48-bits depend on the tag, but must be sufficient to locate the
13 // corresponding entry in the underlying PDB file quickly.  For example, for
14 // a compile unit, we use 2 bytes to represent the index, which allows fast
15 // access to the compile unit's information.
16 //===----------------------------------------------------------------------===//
17 
18 #ifndef LLDB_PLUGINS_SYMBOLFILENATIVEPDB_PDBSYMUID_H
19 #define LLDB_PLUGINS_SYMBOLFILENATIVEPDB_PDBSYMUID_H
20 
21 #include "llvm/DebugInfo/CodeView/SymbolRecord.h"
22 #include "llvm/DebugInfo/PDB/PDBTypes.h"
23 #include "llvm/Support/Compiler.h"
24 
25 #include "lldb/Utility/LLDBAssert.h"
26 #include "lldb/lldb-types.h"
27 
28 namespace lldb_private {
29 namespace npdb {
30 
31 enum class PdbSymUidKind : uint8_t {
32   Compiland,
33   CompilandSym,
34   PublicSym,
35   GlobalSym,
36   Type,
37   FieldListMember
38 };
39 
40 struct PdbCompilandId {
41   // 0-based index of module in PDB
42   uint16_t modi;
43 };
44 
45 struct PdbCompilandSymId {
46   PdbCompilandSymId() = default;
47   PdbCompilandSymId(uint16_t modi, uint32_t offset)
48       : modi(modi), offset(offset) {}
49   // 0-based index of module in PDB
50   uint16_t modi = 0;
51 
52   // Offset of symbol's record in module stream.  This is
53   // offset by 4 from the CVSymbolArray's notion of offset
54   // due to the debug magic at the beginning of the stream.
55   uint32_t offset = 0;
56 };
57 
58 struct PdbGlobalSymId {
59   PdbGlobalSymId() = default;
60   PdbGlobalSymId(uint32_t offset, bool is_public)
61       : offset(offset), is_public(is_public) {}
62 
63   // Offset of symbol's record in globals or publics stream.
64   uint32_t offset = 0;
65 
66   // True if this symbol is in the public stream, false if it's in the globals
67   // stream.
68   bool is_public = false;
69 };
70 
71 struct PdbTypeSymId {
72   PdbTypeSymId() = default;
73   PdbTypeSymId(llvm::codeview::TypeIndex index, bool is_ipi = false)
74       : index(index), is_ipi(is_ipi) {}
75 
76   // The index of the of the type in the TPI or IPI stream.
77   llvm::codeview::TypeIndex index;
78 
79   // True if this symbol comes from the IPI stream, false if it's from the TPI
80   // stream.
81   bool is_ipi = false;
82 };
83 
84 struct PdbFieldListMemberId {
85   // The TypeIndex of the LF_FIELDLIST record.
86   llvm::codeview::TypeIndex index;
87 
88   // The offset from the beginning of the LF_FIELDLIST record to this record.
89   uint16_t offset = 0;
90 };
91 
92 class PdbSymUid {
93   uint64_t m_repr = 0;
94 
95 public:
96   PdbSymUid() = default;
97   PdbSymUid(uint64_t repr) : m_repr(repr) {}
98   PdbSymUid(const PdbCompilandId &cid);
99   PdbSymUid(const PdbCompilandSymId &csid);
100   PdbSymUid(const PdbGlobalSymId &gsid);
101   PdbSymUid(const PdbTypeSymId &tsid);
102   PdbSymUid(const PdbFieldListMemberId &flmid);
103 
104   uint64_t toOpaqueId() const { return m_repr; }
105 
106   PdbSymUidKind kind() const;
107 
108   PdbCompilandId asCompiland() const;
109   PdbCompilandSymId asCompilandSym() const;
110   PdbGlobalSymId asGlobalSym() const;
111   PdbTypeSymId asTypeSym() const;
112   PdbFieldListMemberId asFieldListMember() const;
113 };
114 
115 template <typename T> uint64_t toOpaqueUid(const T &cid) {
116   return PdbSymUid(cid).toOpaqueId();
117 }
118 
119 struct SymbolAndUid {
120   llvm::codeview::CVSymbol sym;
121   PdbSymUid uid;
122 };
123 } // namespace npdb
124 } // namespace lldb_private
125 
126 #endif
127