summaryrefslogtreecommitdiff
path: root/source/Plugins/SymbolFile/NativePDB/PdbSymUid.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/Plugins/SymbolFile/NativePDB/PdbSymUid.cpp')
-rw-r--r--source/Plugins/SymbolFile/NativePDB/PdbSymUid.cpp161
1 files changed, 161 insertions, 0 deletions
diff --git a/source/Plugins/SymbolFile/NativePDB/PdbSymUid.cpp b/source/Plugins/SymbolFile/NativePDB/PdbSymUid.cpp
new file mode 100644
index 000000000000..e5424568da47
--- /dev/null
+++ b/source/Plugins/SymbolFile/NativePDB/PdbSymUid.cpp
@@ -0,0 +1,161 @@
+//===-- PdbSymUid.cpp -------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "PdbSymUid.h"
+
+using namespace lldb_private;
+using namespace lldb_private::npdb;
+using namespace llvm::codeview;
+
+namespace {
+struct GenericIdRepr {
+ uint64_t tag : 4;
+ uint64_t data : 60;
+};
+
+struct CompilandIdRepr {
+ uint64_t tag : 4;
+ uint64_t modi : 16;
+ uint64_t unused : 44;
+};
+
+struct CompilandSymIdRepr {
+ uint64_t tag : 4;
+ uint64_t modi : 16;
+ uint64_t offset : 32;
+ uint64_t unused : 12;
+};
+
+struct GlobalSymIdRepr {
+ uint64_t tag : 4;
+ uint64_t offset : 32;
+ uint64_t pub : 1;
+ uint64_t unused : 27;
+};
+
+struct TypeSymIdRepr {
+ uint64_t tag : 4;
+ uint64_t index : 32;
+ uint64_t ipi : 1;
+ uint64_t unused : 27;
+};
+
+struct FieldListMemberIdRepr {
+ uint64_t tag : 4;
+ uint64_t index : 32;
+ uint64_t offset : 16;
+ uint64_t unused : 12;
+};
+
+static_assert(sizeof(CompilandIdRepr) == 8, "Invalid structure size!");
+static_assert(sizeof(CompilandSymIdRepr) == 8, "Invalid structure size!");
+static_assert(sizeof(GlobalSymIdRepr) == 8, "Invalid structure size!");
+static_assert(sizeof(TypeSymIdRepr) == 8, "Invalid structure size!");
+static_assert(sizeof(FieldListMemberIdRepr) == 8, "Invalid structure size!");
+} // namespace
+
+template <typename OutT, typename InT> static OutT repr_cast(const InT &value) {
+ OutT result;
+ ::memcpy(&result, &value, sizeof(value));
+ return result;
+}
+
+PdbSymUid::PdbSymUid(const PdbCompilandId &cid) {
+ CompilandIdRepr repr;
+ ::memset(&repr, 0, sizeof(repr));
+ repr.modi = cid.modi;
+ repr.tag = static_cast<uint64_t>(PdbSymUidKind::Compiland);
+ m_repr = repr_cast<uint64_t>(repr);
+}
+
+PdbSymUid::PdbSymUid(const PdbCompilandSymId &csid) {
+ CompilandSymIdRepr repr;
+ ::memset(&repr, 0, sizeof(repr));
+ repr.modi = csid.modi;
+ repr.offset = csid.offset;
+ repr.tag = static_cast<uint64_t>(PdbSymUidKind::CompilandSym);
+ m_repr = repr_cast<uint64_t>(repr);
+}
+
+PdbSymUid::PdbSymUid(const PdbGlobalSymId &gsid) {
+ GlobalSymIdRepr repr;
+ ::memset(&repr, 0, sizeof(repr));
+ repr.pub = gsid.is_public;
+ repr.offset = gsid.offset;
+ repr.tag = static_cast<uint64_t>(PdbSymUidKind::GlobalSym);
+ m_repr = repr_cast<uint64_t>(repr);
+}
+
+PdbSymUid::PdbSymUid(const PdbTypeSymId &tsid) {
+ TypeSymIdRepr repr;
+ ::memset(&repr, 0, sizeof(repr));
+ repr.index = tsid.index.getIndex();
+ repr.ipi = tsid.is_ipi;
+ repr.tag = static_cast<uint64_t>(PdbSymUidKind::Type);
+ m_repr = repr_cast<uint64_t>(repr);
+}
+
+PdbSymUid::PdbSymUid(const PdbFieldListMemberId &flmid) {
+ FieldListMemberIdRepr repr;
+ ::memset(&repr, 0, sizeof(repr));
+ repr.index = flmid.index.getIndex();
+ repr.offset = flmid.offset;
+ repr.tag = static_cast<uint64_t>(PdbSymUidKind::FieldListMember);
+ m_repr = repr_cast<uint64_t>(repr);
+}
+
+PdbSymUidKind PdbSymUid::kind() const {
+ GenericIdRepr generic = repr_cast<GenericIdRepr>(m_repr);
+ return static_cast<PdbSymUidKind>(generic.tag);
+}
+
+PdbCompilandId PdbSymUid::asCompiland() const {
+ assert(kind() == PdbSymUidKind::Compiland);
+ auto repr = repr_cast<CompilandIdRepr>(m_repr);
+ PdbCompilandId result;
+ result.modi = repr.modi;
+ return result;
+}
+
+PdbCompilandSymId PdbSymUid::asCompilandSym() const {
+ assert(kind() == PdbSymUidKind::CompilandSym);
+ auto repr = repr_cast<CompilandSymIdRepr>(m_repr);
+ PdbCompilandSymId result;
+ result.modi = repr.modi;
+ result.offset = repr.offset;
+ return result;
+}
+
+PdbGlobalSymId PdbSymUid::asGlobalSym() const {
+ assert(kind() == PdbSymUidKind::GlobalSym ||
+ kind() == PdbSymUidKind::PublicSym);
+ auto repr = repr_cast<GlobalSymIdRepr>(m_repr);
+ PdbGlobalSymId result;
+ result.is_public = repr.pub;
+ result.offset = repr.offset;
+ return result;
+}
+
+PdbTypeSymId PdbSymUid::asTypeSym() const {
+ assert(kind() == PdbSymUidKind::Type);
+ auto repr = repr_cast<TypeSymIdRepr>(m_repr);
+ PdbTypeSymId result;
+ result.index.setIndex(repr.index);
+ result.is_ipi = repr.ipi;
+ return result;
+}
+
+PdbFieldListMemberId PdbSymUid::asFieldListMember() const {
+ assert(kind() == PdbSymUidKind::FieldListMember);
+ auto repr = repr_cast<FieldListMemberIdRepr>(m_repr);
+ PdbFieldListMemberId result;
+ result.index.setIndex(repr.index);
+ result.offset = repr.offset;
+ return result;
+}