1 | //===-- PdbSymUid.cpp -----------------------------------------------------===// |
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(dest: &result, src: &value, n: sizeof(value)); |
65 | return result; |
66 | } |
67 | |
68 | PdbSymUid::PdbSymUid(const PdbCompilandId &cid) { |
69 | CompilandIdRepr repr; |
70 | ::memset(s: &repr, c: 0, n: sizeof(repr)); |
71 | repr.modi = cid.modi; |
72 | repr.tag = static_cast<uint64_t>(PdbSymUidKind::Compiland); |
73 | m_repr = repr_cast<uint64_t>(value: repr); |
74 | } |
75 | |
76 | PdbSymUid::PdbSymUid(const PdbCompilandSymId &csid) { |
77 | CompilandSymIdRepr repr; |
78 | ::memset(s: &repr, c: 0, n: 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>(value: repr); |
83 | } |
84 | |
85 | PdbSymUid::PdbSymUid(const PdbGlobalSymId &gsid) { |
86 | GlobalSymIdRepr repr; |
87 | ::memset(s: &repr, c: 0, n: 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>(value: repr); |
92 | } |
93 | |
94 | PdbSymUid::PdbSymUid(const PdbTypeSymId &tsid) { |
95 | TypeSymIdRepr repr; |
96 | ::memset(s: &repr, c: 0, n: 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>(value: repr); |
101 | } |
102 | |
103 | PdbSymUid::PdbSymUid(const PdbFieldListMemberId &flmid) { |
104 | FieldListMemberIdRepr repr; |
105 | ::memset(s: &repr, c: 0, n: 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>(value: repr); |
110 | } |
111 | |
112 | PdbSymUidKind PdbSymUid::kind() const { |
113 | GenericIdRepr generic = repr_cast<GenericIdRepr>(value: 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>(value: 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>(value: 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>(value: 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>(value: 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>(value: m_repr); |
156 | PdbFieldListMemberId result; |
157 | result.index.setIndex(repr.index); |
158 | result.offset = repr.offset; |
159 | return result; |
160 | } |
161 | |