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