1 //===-- PdbSymUid.cpp -------------------------------------------*- 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 10 #include "PdbSymUid.h" 11 12 using namespace lldb_private; 13 using namespace lldb_private::npdb; 14 using namespace llvm::codeview; 15 16 namespace { 17 struct GenericIdRepr { 18 uint64_t tag : 4; 19 uint64_t data : 60; 20 }; 21 22 struct CompilandIdRepr { 23 uint64_t tag : 4; 24 uint64_t modi : 16; 25 uint64_t unused : 44; 26 }; 27 28 struct CompilandSymIdRepr { 29 uint64_t tag : 4; 30 uint64_t modi : 16; 31 uint64_t offset : 32; 32 uint64_t unused : 12; 33 }; 34 35 struct GlobalSymIdRepr { 36 uint64_t tag : 4; 37 uint64_t offset : 32; 38 uint64_t pub : 1; 39 uint64_t unused : 27; 40 }; 41 42 struct TypeSymIdRepr { 43 uint64_t tag : 4; 44 uint64_t index : 32; 45 uint64_t ipi : 1; 46 uint64_t unused : 27; 47 }; 48 49 struct FieldListMemberIdRepr { 50 uint64_t tag : 4; 51 uint64_t index : 32; 52 uint64_t offset : 16; 53 uint64_t unused : 12; 54 }; 55 56 static_assert(sizeof(CompilandIdRepr) == 8, "Invalid structure size!"); 57 static_assert(sizeof(CompilandSymIdRepr) == 8, "Invalid structure size!"); 58 static_assert(sizeof(GlobalSymIdRepr) == 8, "Invalid structure size!"); 59 static_assert(sizeof(TypeSymIdRepr) == 8, "Invalid structure size!"); 60 static_assert(sizeof(FieldListMemberIdRepr) == 8, "Invalid structure size!"); 61 } // namespace 62 63 template <typename OutT, typename InT> static OutT repr_cast(const InT &value) { 64 OutT result; 65 ::memcpy(&result, &value, sizeof(value)); 66 return result; 67 } 68 69 PdbSymUid::PdbSymUid(const PdbCompilandId &cid) { 70 CompilandIdRepr repr; 71 ::memset(&repr, 0, sizeof(repr)); 72 repr.modi = cid.modi; 73 repr.tag = static_cast<uint64_t>(PdbSymUidKind::Compiland); 74 m_repr = repr_cast<uint64_t>(repr); 75 } 76 77 PdbSymUid::PdbSymUid(const PdbCompilandSymId &csid) { 78 CompilandSymIdRepr repr; 79 ::memset(&repr, 0, sizeof(repr)); 80 repr.modi = csid.modi; 81 repr.offset = csid.offset; 82 repr.tag = static_cast<uint64_t>(PdbSymUidKind::CompilandSym); 83 m_repr = repr_cast<uint64_t>(repr); 84 } 85 86 PdbSymUid::PdbSymUid(const PdbGlobalSymId &gsid) { 87 GlobalSymIdRepr repr; 88 ::memset(&repr, 0, sizeof(repr)); 89 repr.pub = gsid.is_public; 90 repr.offset = gsid.offset; 91 repr.tag = static_cast<uint64_t>(PdbSymUidKind::GlobalSym); 92 m_repr = repr_cast<uint64_t>(repr); 93 } 94 95 PdbSymUid::PdbSymUid(const PdbTypeSymId &tsid) { 96 TypeSymIdRepr repr; 97 ::memset(&repr, 0, sizeof(repr)); 98 repr.index = tsid.index.getIndex(); 99 repr.ipi = tsid.is_ipi; 100 repr.tag = static_cast<uint64_t>(PdbSymUidKind::Type); 101 m_repr = repr_cast<uint64_t>(repr); 102 } 103 104 PdbSymUid::PdbSymUid(const PdbFieldListMemberId &flmid) { 105 FieldListMemberIdRepr repr; 106 ::memset(&repr, 0, sizeof(repr)); 107 repr.index = flmid.index.getIndex(); 108 repr.offset = flmid.offset; 109 repr.tag = static_cast<uint64_t>(PdbSymUidKind::FieldListMember); 110 m_repr = repr_cast<uint64_t>(repr); 111 } 112 113 PdbSymUidKind PdbSymUid::kind() const { 114 GenericIdRepr generic = repr_cast<GenericIdRepr>(m_repr); 115 return static_cast<PdbSymUidKind>(generic.tag); 116 } 117 118 PdbCompilandId PdbSymUid::asCompiland() const { 119 assert(kind() == PdbSymUidKind::Compiland); 120 auto repr = repr_cast<CompilandIdRepr>(m_repr); 121 PdbCompilandId result; 122 result.modi = repr.modi; 123 return result; 124 } 125 126 PdbCompilandSymId PdbSymUid::asCompilandSym() const { 127 assert(kind() == PdbSymUidKind::CompilandSym); 128 auto repr = repr_cast<CompilandSymIdRepr>(m_repr); 129 PdbCompilandSymId result; 130 result.modi = repr.modi; 131 result.offset = repr.offset; 132 return result; 133 } 134 135 PdbGlobalSymId PdbSymUid::asGlobalSym() const { 136 assert(kind() == PdbSymUidKind::GlobalSym || 137 kind() == PdbSymUidKind::PublicSym); 138 auto repr = repr_cast<GlobalSymIdRepr>(m_repr); 139 PdbGlobalSymId result; 140 result.is_public = repr.pub; 141 result.offset = repr.offset; 142 return result; 143 } 144 145 PdbTypeSymId PdbSymUid::asTypeSym() const { 146 assert(kind() == PdbSymUidKind::Type); 147 auto repr = repr_cast<TypeSymIdRepr>(m_repr); 148 PdbTypeSymId result; 149 result.index.setIndex(repr.index); 150 result.is_ipi = repr.ipi; 151 return result; 152 } 153 154 PdbFieldListMemberId PdbSymUid::asFieldListMember() const { 155 assert(kind() == PdbSymUidKind::FieldListMember); 156 auto repr = repr_cast<FieldListMemberIdRepr>(m_repr); 157 PdbFieldListMemberId result; 158 result.index.setIndex(repr.index); 159 result.offset = repr.offset; 160 return result; 161 } 162