summaryrefslogtreecommitdiffstats
path: root/lldb/source/Plugins/SymbolFile/NativePDB/PdbSymUid.h
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source/Plugins/SymbolFile/NativePDB/PdbSymUid.h')
-rw-r--r--lldb/source/Plugins/SymbolFile/NativePDB/PdbSymUid.h233
1 files changed, 63 insertions, 170 deletions
diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/PdbSymUid.h b/lldb/source/Plugins/SymbolFile/NativePDB/PdbSymUid.h
index f43e0f90f9b..4794c5b30c8 100644
--- a/lldb/source/Plugins/SymbolFile/NativePDB/PdbSymUid.h
+++ b/lldb/source/Plugins/SymbolFile/NativePDB/PdbSymUid.h
@@ -28,189 +28,82 @@
namespace lldb_private {
namespace npdb {
-// **important** - All concrete id types must have the 1-byte tag field at
-// the beginning so that the types are all layout-compatible with each
-// other, which is necessary in order to be able to safely access the tag
-// member through any union member.
+enum class PdbSymUidKind : uint8_t {
+ Compiland,
+ CompilandSym,
+ PublicSym,
+ GlobalSym,
+ Type,
+ FieldListMember
+};
+
struct PdbCompilandId {
- uint64_t tag : 8; // PDB_SymType::Compiland
- uint64_t modi : 16; // 0-based index of module in PDB
- uint64_t unused : 32;
+ // 0-based index of module in PDB
+ uint16_t modi;
+};
+
+struct PdbCompilandSymId {
+ // 0-based index of module in PDB
+ uint16_t modi = 0;
+
+ // Offset of symbol's record in module stream. This is
+ // offset by 4 from the CVSymbolArray's notion of offset
+ // due to the debug magic at the beginning of the stream.
+ uint32_t offset = 0;
};
-struct PdbCuSymId {
- uint64_t tag : 8; // PDB_SymType::Data, Function, Block, etc.
- uint64_t
- offset : 30; // Offset of symbol's record in module stream. This is
- // offset by 4 from the CVSymbolArray's notion of offset
- // due to the debug magic at the beginning of the stream.
- uint64_t global : 1; // True if this is from the globals stream.
- uint64_t unused : 1;
- uint64_t modi : 16; // For non-global, this is the 0-based index of module.
+
+struct PdbGlobalSymId {
+ // Offset of symbol's record in globals or publics stream.
+ uint32_t offset = 0;
+
+ // True if this symbol is in the public stream, false if it's in the globals
+ // stream.
+ bool is_public = false;
};
struct PdbTypeSymId {
- uint64_t tag : 8; // PDB_SymType::FunctionSig, Enum, PointerType, etc.
- uint64_t is_ipi : 8; // 1 if this value is from the IPI stream, 0 for TPI.
- uint64_t unused : 16;
- uint64_t index : 32; // codeview::TypeIndex
+ // The index of the of the type in the TPI or IPI stream.
+ llvm::codeview::TypeIndex index;
+
+ // True if this symbol comes from the IPI stream, false if it's from the TPI
+ // stream.
+ bool is_ipi = false;
};
-static_assert(sizeof(PdbCompilandId) == 8, "invalid uid size");
-static_assert(sizeof(PdbCuSymId) == 8, "invalid uid size");
-static_assert(std::is_standard_layout<PdbCompilandId>::value,
- "type is not standard layout!");
-static_assert(std::is_standard_layout<PdbCuSymId>::value,
- "type is not standard layout!");
+struct PdbFieldListMemberId {
+ // The TypeIndex of the LF_FIELDLIST record.
+ llvm::codeview::TypeIndex index;
-class PdbSymUid {
- union {
- PdbCompilandId comp_id;
- PdbCuSymId cu_sym;
- PdbTypeSymId type_sym;
- } m_uid;
+ // The offset from the beginning of the LF_FIELDLIST record to this record.
+ uint16_t offset = 0;
+};
- PdbSymUid() { ::memset(&m_uid, 0, sizeof(m_uid)); }
+class PdbSymUid {
+ uint64_t m_repr = 0;
public:
- static bool isTypeSym(llvm::pdb::PDB_SymType tag) {
- switch (tag) {
- case llvm::pdb::PDB_SymType::ArrayType:
- case llvm::pdb::PDB_SymType::BaseClass:
- case llvm::pdb::PDB_SymType::BaseInterface:
- case llvm::pdb::PDB_SymType::BuiltinType:
- case llvm::pdb::PDB_SymType::CustomType:
- case llvm::pdb::PDB_SymType::Enum:
- case llvm::pdb::PDB_SymType::FunctionArg:
- case llvm::pdb::PDB_SymType::FunctionSig:
- case llvm::pdb::PDB_SymType::Typedef:
- case llvm::pdb::PDB_SymType::VectorType:
- case llvm::pdb::PDB_SymType::VTableShape:
- case llvm::pdb::PDB_SymType::PointerType:
- case llvm::pdb::PDB_SymType::UDT:
- return true;
- default:
- return false;
- }
- }
-
- static bool isCuSym(llvm::pdb::PDB_SymType tag) {
- switch (tag) {
- case llvm::pdb::PDB_SymType::Block:
- case llvm::pdb::PDB_SymType::Callee:
- case llvm::pdb::PDB_SymType::Caller:
- case llvm::pdb::PDB_SymType::CallSite:
- case llvm::pdb::PDB_SymType::CoffGroup:
- case llvm::pdb::PDB_SymType::CompilandDetails:
- case llvm::pdb::PDB_SymType::CompilandEnv:
- case llvm::pdb::PDB_SymType::Custom:
- case llvm::pdb::PDB_SymType::Data:
- case llvm::pdb::PDB_SymType::Function:
- case llvm::pdb::PDB_SymType::Inlinee:
- case llvm::pdb::PDB_SymType::InlineSite:
- case llvm::pdb::PDB_SymType::Label:
- case llvm::pdb::PDB_SymType::Thunk:
- return true;
- default:
- return false;
- }
- }
-
- static PdbSymUid makeCuSymId(llvm::codeview::ProcRefSym sym) {
- return makeCuSymId(llvm::pdb::PDB_SymType::Function, sym.Module - 1,
- sym.SymOffset);
- }
-
- static PdbSymUid makeCuSymId(llvm::pdb::PDB_SymType type, uint16_t modi,
- uint32_t offset) {
- lldbassert(isCuSym(type));
-
- PdbSymUid uid;
- uid.m_uid.cu_sym.modi = modi;
- uid.m_uid.cu_sym.offset = offset;
- uid.m_uid.cu_sym.global = false;
- uid.m_uid.cu_sym.tag = static_cast<uint8_t>(type);
- return uid;
- }
-
- static PdbSymUid makeGlobalVariableUid(uint32_t offset) {
- PdbSymUid uid = {};
- uid.m_uid.cu_sym.modi = 0;
- uid.m_uid.cu_sym.offset = offset;
- uid.m_uid.cu_sym.global = 1;
- uid.m_uid.cu_sym.unused = 0;
- uid.m_uid.cu_sym.tag = static_cast<uint8_t>(llvm::pdb::PDB_SymType::Data);
- return uid;
- }
-
- static PdbSymUid makeCompilandId(llvm::codeview::ProcRefSym sym) {
- // S_PROCREF symbols are 1-based
- lldbassert(sym.Module > 0);
- return makeCompilandId(sym.Module - 1);
- }
-
- static PdbSymUid makeCompilandId(uint16_t modi) {
- PdbSymUid uid;
- uid.m_uid.comp_id.modi = modi;
- uid.m_uid.cu_sym.tag =
- static_cast<uint8_t>(llvm::pdb::PDB_SymType::Compiland);
- return uid;
- }
-
- static PdbSymUid makeTypeSymId(llvm::pdb::PDB_SymType type,
- llvm::codeview::TypeIndex index, bool is_ipi) {
- lldbassert(isTypeSym(type));
-
- PdbSymUid uid;
- uid.m_uid.type_sym.tag = static_cast<uint8_t>(type);
- uid.m_uid.type_sym.index = index.getIndex();
- uid.m_uid.type_sym.is_ipi = static_cast<uint8_t>(is_ipi);
- return uid;
- }
-
- static PdbSymUid fromOpaqueId(uint64_t value) {
- PdbSymUid result;
- ::memcpy(&result.m_uid, &value, sizeof(value));
- return result;
- }
-
- uint64_t toOpaqueId() const {
- uint64_t result;
- ::memcpy(&result, &m_uid, sizeof(m_uid));
- return result;
- }
-
- bool isPubSym() const {
- return tag() == llvm::pdb::PDB_SymType::PublicSymbol;
- }
- bool isCompiland() const {
- return tag() == llvm::pdb::PDB_SymType::Compiland;
- }
- bool isGlobalVariable() const {
- if (tag() != llvm::pdb::PDB_SymType::Data)
- return false;
- return static_cast<bool>(asCuSym().global);
- }
-
- llvm::pdb::PDB_SymType tag() const {
- return static_cast<llvm::pdb::PDB_SymType>(m_uid.comp_id.tag);
- }
-
- const PdbCompilandId &asCompiland() const {
- lldbassert(tag() == llvm::pdb::PDB_SymType::Compiland);
- return m_uid.comp_id;
- }
-
- const PdbCuSymId &asCuSym() const {
- lldbassert(isCuSym(tag()));
- return m_uid.cu_sym;
- }
-
- const PdbTypeSymId &asTypeSym() const {
- lldbassert(isTypeSym(tag()));
- return m_uid.type_sym;
- }
+ PdbSymUid(uint64_t repr) : m_repr(repr) {}
+ PdbSymUid(const PdbCompilandId &cid);
+ PdbSymUid(const PdbCompilandSymId &csid);
+ PdbSymUid(const PdbGlobalSymId &gsid);
+ PdbSymUid(const PdbTypeSymId &tsid);
+ PdbSymUid(const PdbFieldListMemberId &flmid);
+
+ uint64_t toOpaqueId() const { return m_repr; }
+
+ PdbSymUidKind kind() const;
+
+ PdbCompilandId asCompiland() const;
+ PdbCompilandSymId asCompilandSym() const;
+ PdbGlobalSymId asGlobalSym() const;
+ PdbTypeSymId asTypeSym() const;
+ PdbFieldListMemberId asFieldListMember() const;
};
+template <typename T> uint64_t toOpaqueUid(const T &cid) {
+ return PdbSymUid(cid).toOpaqueId();
+}
+
struct SymbolAndUid {
llvm::codeview::CVSymbol sym;
PdbSymUid uid;
OpenPOWER on IntegriCloud