1343181Sdim//===-- PdbSymUid.h ---------------------------------------------*- C++ -*-===//
2343181Sdim//
3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4353358Sdim// See https://llvm.org/LICENSE.txt for license information.
5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6343181Sdim//
7343181Sdim//===----------------------------------------------------------------------===//
8343181Sdim// A unique identification scheme for Pdb records.
9343181Sdim// The scheme is to partition a 64-bit integer into an 8-bit tag field, which
10343181Sdim// will contain some value from the PDB_SymType enumeration.  The format of the
11343181Sdim// other 48-bits depend on the tag, but must be sufficient to locate the
12343181Sdim// corresponding entry in the underlying PDB file quickly.  For example, for
13343181Sdim// a compile unit, we use 2 bytes to represent the index, which allows fast
14343181Sdim// access to the compile unit's information.
15343181Sdim//===----------------------------------------------------------------------===//
16343181Sdim
17343181Sdim#ifndef LLDB_PLUGINS_SYMBOLFILENATIVEPDB_PDBSYMUID_H
18343181Sdim#define LLDB_PLUGINS_SYMBOLFILENATIVEPDB_PDBSYMUID_H
19343181Sdim
20343181Sdim#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
21343181Sdim#include "llvm/DebugInfo/PDB/PDBTypes.h"
22343181Sdim#include "llvm/Support/Compiler.h"
23343181Sdim
24343181Sdim#include "lldb/Utility/LLDBAssert.h"
25343181Sdim#include "lldb/lldb-types.h"
26343181Sdim
27343181Sdimnamespace lldb_private {
28343181Sdimnamespace npdb {
29343181Sdim
30343181Sdimenum class PdbSymUidKind : uint8_t {
31343181Sdim  Compiland,
32343181Sdim  CompilandSym,
33343181Sdim  PublicSym,
34343181Sdim  GlobalSym,
35343181Sdim  Type,
36343181Sdim  FieldListMember
37343181Sdim};
38343181Sdim
39343181Sdimstruct PdbCompilandId {
40343181Sdim  // 0-based index of module in PDB
41343181Sdim  uint16_t modi;
42343181Sdim};
43343181Sdim
44343181Sdimstruct PdbCompilandSymId {
45343181Sdim  PdbCompilandSymId() = default;
46343181Sdim  PdbCompilandSymId(uint16_t modi, uint32_t offset)
47343181Sdim      : modi(modi), offset(offset) {}
48343181Sdim  // 0-based index of module in PDB
49343181Sdim  uint16_t modi = 0;
50343181Sdim
51343181Sdim  // Offset of symbol's record in module stream.  This is
52343181Sdim  // offset by 4 from the CVSymbolArray's notion of offset
53343181Sdim  // due to the debug magic at the beginning of the stream.
54343181Sdim  uint32_t offset = 0;
55343181Sdim};
56343181Sdim
57343181Sdimstruct PdbGlobalSymId {
58343181Sdim  PdbGlobalSymId() = default;
59343181Sdim  PdbGlobalSymId(uint32_t offset, bool is_public)
60343181Sdim      : offset(offset), is_public(is_public) {}
61343181Sdim
62343181Sdim  // Offset of symbol's record in globals or publics stream.
63343181Sdim  uint32_t offset = 0;
64343181Sdim
65343181Sdim  // True if this symbol is in the public stream, false if it's in the globals
66343181Sdim  // stream.
67343181Sdim  bool is_public = false;
68343181Sdim};
69343181Sdim
70343181Sdimstruct PdbTypeSymId {
71343181Sdim  PdbTypeSymId() = default;
72343181Sdim  PdbTypeSymId(llvm::codeview::TypeIndex index, bool is_ipi = false)
73343181Sdim      : index(index), is_ipi(is_ipi) {}
74343181Sdim
75343181Sdim  // The index of the of the type in the TPI or IPI stream.
76343181Sdim  llvm::codeview::TypeIndex index;
77343181Sdim
78343181Sdim  // True if this symbol comes from the IPI stream, false if it's from the TPI
79343181Sdim  // stream.
80343181Sdim  bool is_ipi = false;
81343181Sdim};
82343181Sdim
83343181Sdimstruct PdbFieldListMemberId {
84343181Sdim  // The TypeIndex of the LF_FIELDLIST record.
85343181Sdim  llvm::codeview::TypeIndex index;
86343181Sdim
87343181Sdim  // The offset from the beginning of the LF_FIELDLIST record to this record.
88343181Sdim  uint16_t offset = 0;
89343181Sdim};
90343181Sdim
91343181Sdimclass PdbSymUid {
92343181Sdim  uint64_t m_repr = 0;
93343181Sdim
94343181Sdimpublic:
95343181Sdim  PdbSymUid() = default;
96343181Sdim  PdbSymUid(uint64_t repr) : m_repr(repr) {}
97343181Sdim  PdbSymUid(const PdbCompilandId &cid);
98343181Sdim  PdbSymUid(const PdbCompilandSymId &csid);
99343181Sdim  PdbSymUid(const PdbGlobalSymId &gsid);
100343181Sdim  PdbSymUid(const PdbTypeSymId &tsid);
101343181Sdim  PdbSymUid(const PdbFieldListMemberId &flmid);
102343181Sdim
103343181Sdim  uint64_t toOpaqueId() const { return m_repr; }
104343181Sdim
105343181Sdim  PdbSymUidKind kind() const;
106343181Sdim
107343181Sdim  PdbCompilandId asCompiland() const;
108343181Sdim  PdbCompilandSymId asCompilandSym() const;
109343181Sdim  PdbGlobalSymId asGlobalSym() const;
110343181Sdim  PdbTypeSymId asTypeSym() const;
111343181Sdim  PdbFieldListMemberId asFieldListMember() const;
112343181Sdim};
113343181Sdim
114343181Sdimtemplate <typename T> uint64_t toOpaqueUid(const T &cid) {
115343181Sdim  return PdbSymUid(cid).toOpaqueId();
116343181Sdim}
117343181Sdim
118343181Sdimstruct SymbolAndUid {
119343181Sdim  llvm::codeview::CVSymbol sym;
120343181Sdim  PdbSymUid uid;
121343181Sdim};
122343181Sdim} // namespace npdb
123343181Sdim} // namespace lldb_private
124343181Sdim
125343181Sdim#endif
126