10b57cec5SDimitry Andric //===-- PdbSymUid.h ---------------------------------------------*- C++ -*-===//
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 // A unique identification scheme for Pdb records.
90b57cec5SDimitry Andric // The scheme is to partition a 64-bit integer into an 8-bit tag field, which
100b57cec5SDimitry Andric // will contain some value from the PDB_SymType enumeration.  The format of the
110b57cec5SDimitry Andric // other 48-bits depend on the tag, but must be sufficient to locate the
120b57cec5SDimitry Andric // corresponding entry in the underlying PDB file quickly.  For example, for
130b57cec5SDimitry Andric // a compile unit, we use 2 bytes to represent the index, which allows fast
140b57cec5SDimitry Andric // access to the compile unit's information.
150b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
160b57cec5SDimitry Andric 
170b57cec5SDimitry Andric #ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_NATIVEPDB_PDBSYMUID_H
180b57cec5SDimitry Andric #define LLDB_SOURCE_PLUGINS_SYMBOLFILE_NATIVEPDB_PDBSYMUID_H
190b57cec5SDimitry Andric 
200b57cec5SDimitry Andric #include "llvm/DebugInfo/CodeView/SymbolRecord.h"
210b57cec5SDimitry Andric #include "llvm/DebugInfo/PDB/PDBTypes.h"
220b57cec5SDimitry Andric #include "llvm/Support/Compiler.h"
230b57cec5SDimitry Andric 
240b57cec5SDimitry Andric #include "lldb/Utility/LLDBAssert.h"
250b57cec5SDimitry Andric #include "lldb/lldb-types.h"
260b57cec5SDimitry Andric 
270b57cec5SDimitry Andric namespace lldb_private {
280b57cec5SDimitry Andric namespace npdb {
290b57cec5SDimitry Andric 
300b57cec5SDimitry Andric enum class PdbSymUidKind : uint8_t {
310b57cec5SDimitry Andric   Compiland,
320b57cec5SDimitry Andric   CompilandSym,
330b57cec5SDimitry Andric   PublicSym,
340b57cec5SDimitry Andric   GlobalSym,
350b57cec5SDimitry Andric   Type,
360b57cec5SDimitry Andric   FieldListMember
370b57cec5SDimitry Andric };
380b57cec5SDimitry Andric 
390b57cec5SDimitry Andric struct PdbCompilandId {
400b57cec5SDimitry Andric   // 0-based index of module in PDB
410b57cec5SDimitry Andric   uint16_t modi;
420b57cec5SDimitry Andric };
430b57cec5SDimitry Andric 
440b57cec5SDimitry Andric struct PdbCompilandSymId {
450b57cec5SDimitry Andric   PdbCompilandSymId() = default;
PdbCompilandSymIdPdbCompilandSymId460b57cec5SDimitry Andric   PdbCompilandSymId(uint16_t modi, uint32_t offset)
470b57cec5SDimitry Andric       : modi(modi), offset(offset) {}
480b57cec5SDimitry Andric   // 0-based index of module in PDB
490b57cec5SDimitry Andric   uint16_t modi = 0;
500b57cec5SDimitry Andric 
510b57cec5SDimitry Andric   // Offset of symbol's record in module stream.  This is
520b57cec5SDimitry Andric   // offset by 4 from the CVSymbolArray's notion of offset
530b57cec5SDimitry Andric   // due to the debug magic at the beginning of the stream.
540b57cec5SDimitry Andric   uint32_t offset = 0;
550b57cec5SDimitry Andric };
560b57cec5SDimitry Andric 
570b57cec5SDimitry Andric struct PdbGlobalSymId {
580b57cec5SDimitry Andric   PdbGlobalSymId() = default;
PdbGlobalSymIdPdbGlobalSymId590b57cec5SDimitry Andric   PdbGlobalSymId(uint32_t offset, bool is_public)
600b57cec5SDimitry Andric       : offset(offset), is_public(is_public) {}
610b57cec5SDimitry Andric 
620b57cec5SDimitry Andric   // Offset of symbol's record in globals or publics stream.
630b57cec5SDimitry Andric   uint32_t offset = 0;
640b57cec5SDimitry Andric 
650b57cec5SDimitry Andric   // True if this symbol is in the public stream, false if it's in the globals
660b57cec5SDimitry Andric   // stream.
670b57cec5SDimitry Andric   bool is_public = false;
680b57cec5SDimitry Andric };
690b57cec5SDimitry Andric 
700b57cec5SDimitry Andric struct PdbTypeSymId {
710b57cec5SDimitry Andric   PdbTypeSymId() = default;
720b57cec5SDimitry Andric   PdbTypeSymId(llvm::codeview::TypeIndex index, bool is_ipi = false)
indexPdbTypeSymId730b57cec5SDimitry Andric       : index(index), is_ipi(is_ipi) {}
740b57cec5SDimitry Andric 
750b57cec5SDimitry Andric   // The index of the of the type in the TPI or IPI stream.
760b57cec5SDimitry Andric   llvm::codeview::TypeIndex index;
770b57cec5SDimitry Andric 
780b57cec5SDimitry Andric   // True if this symbol comes from the IPI stream, false if it's from the TPI
790b57cec5SDimitry Andric   // stream.
800b57cec5SDimitry Andric   bool is_ipi = false;
810b57cec5SDimitry Andric };
820b57cec5SDimitry Andric 
830b57cec5SDimitry Andric struct PdbFieldListMemberId {
840b57cec5SDimitry Andric   // The TypeIndex of the LF_FIELDLIST record.
850b57cec5SDimitry Andric   llvm::codeview::TypeIndex index;
860b57cec5SDimitry Andric 
870b57cec5SDimitry Andric   // The offset from the beginning of the LF_FIELDLIST record to this record.
880b57cec5SDimitry Andric   uint16_t offset = 0;
890b57cec5SDimitry Andric };
900b57cec5SDimitry Andric 
910b57cec5SDimitry Andric class PdbSymUid {
920b57cec5SDimitry Andric   uint64_t m_repr = 0;
930b57cec5SDimitry Andric 
940b57cec5SDimitry Andric public:
950b57cec5SDimitry Andric   PdbSymUid() = default;
PdbSymUid(uint64_t repr)960b57cec5SDimitry Andric   PdbSymUid(uint64_t repr) : m_repr(repr) {}
970b57cec5SDimitry Andric   PdbSymUid(const PdbCompilandId &cid);
980b57cec5SDimitry Andric   PdbSymUid(const PdbCompilandSymId &csid);
990b57cec5SDimitry Andric   PdbSymUid(const PdbGlobalSymId &gsid);
1000b57cec5SDimitry Andric   PdbSymUid(const PdbTypeSymId &tsid);
1010b57cec5SDimitry Andric   PdbSymUid(const PdbFieldListMemberId &flmid);
1020b57cec5SDimitry Andric 
toOpaqueId()1030b57cec5SDimitry Andric   uint64_t toOpaqueId() const { return m_repr; }
1040b57cec5SDimitry Andric 
1050b57cec5SDimitry Andric   PdbSymUidKind kind() const;
1060b57cec5SDimitry Andric 
1070b57cec5SDimitry Andric   PdbCompilandId asCompiland() const;
1080b57cec5SDimitry Andric   PdbCompilandSymId asCompilandSym() const;
1090b57cec5SDimitry Andric   PdbGlobalSymId asGlobalSym() const;
1100b57cec5SDimitry Andric   PdbTypeSymId asTypeSym() const;
1110b57cec5SDimitry Andric   PdbFieldListMemberId asFieldListMember() const;
1120b57cec5SDimitry Andric };
1130b57cec5SDimitry Andric 
toOpaqueUid(const T & cid)1140b57cec5SDimitry Andric template <typename T> uint64_t toOpaqueUid(const T &cid) {
1150b57cec5SDimitry Andric   return PdbSymUid(cid).toOpaqueId();
1160b57cec5SDimitry Andric }
1170b57cec5SDimitry Andric 
1180b57cec5SDimitry Andric struct SymbolAndUid {
1190b57cec5SDimitry Andric   llvm::codeview::CVSymbol sym;
1200b57cec5SDimitry Andric   PdbSymUid uid;
1210b57cec5SDimitry Andric };
1220b57cec5SDimitry Andric } // namespace npdb
1230b57cec5SDimitry Andric } // namespace lldb_private
1240b57cec5SDimitry Andric 
1250b57cec5SDimitry Andric #endif
126