1 | //===-- PdbUtil.h -----------------------------------------------*- 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 | #ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_NATIVEPDB_PDBUTIL_H |
10 | #define LLDB_SOURCE_PLUGINS_SYMBOLFILE_NATIVEPDB_PDBUTIL_H |
11 | |
12 | #include "lldb/Expression/DWARFExpression.h" |
13 | #include "lldb/Symbol/Variable.h" |
14 | #include "lldb/lldb-enumerations.h" |
15 | |
16 | #include "llvm/DebugInfo/CodeView/CodeView.h" |
17 | #include "llvm/DebugInfo/CodeView/SymbolRecord.h" |
18 | #include "llvm/DebugInfo/CodeView/TypeRecord.h" |
19 | #include "llvm/DebugInfo/PDB/PDBTypes.h" |
20 | |
21 | #include "PdbSymUid.h" |
22 | |
23 | #include <tuple> |
24 | #include <utility> |
25 | |
26 | namespace llvm { |
27 | namespace pdb { |
28 | class TpiStream; |
29 | } |
30 | } // namespace llvm |
31 | |
32 | namespace lldb_private { |
33 | namespace npdb { |
34 | |
35 | class PdbIndex; |
36 | |
37 | struct CVTagRecord { |
38 | enum Kind { Class, Struct, Union, Enum }; |
39 | |
40 | static CVTagRecord create(llvm::codeview::CVType type); |
41 | |
42 | Kind kind() const { return m_kind; } |
43 | |
44 | const llvm::codeview::TagRecord &asTag() const { |
45 | if (m_kind == Struct || m_kind == Class) |
46 | return cvclass; |
47 | if (m_kind == Enum) |
48 | return cvenum; |
49 | return cvunion; |
50 | } |
51 | |
52 | const llvm::codeview::ClassRecord &asClass() const { |
53 | assert(m_kind == Struct || m_kind == Class); |
54 | return cvclass; |
55 | } |
56 | |
57 | const llvm::codeview::EnumRecord &asEnum() const { |
58 | assert(m_kind == Enum); |
59 | return cvenum; |
60 | } |
61 | |
62 | const llvm::codeview::UnionRecord &asUnion() const { |
63 | assert(m_kind == Union); |
64 | return cvunion; |
65 | } |
66 | |
67 | llvm::StringRef name() const { |
68 | if (m_kind == Struct || m_kind == Union) |
69 | return cvclass.Name; |
70 | if (m_kind == Enum) |
71 | return cvenum.Name; |
72 | return cvunion.Name; |
73 | } |
74 | |
75 | private: |
76 | CVTagRecord(llvm::codeview::ClassRecord &&c); |
77 | CVTagRecord(llvm::codeview::UnionRecord &&u); |
78 | CVTagRecord(llvm::codeview::EnumRecord &&e); |
79 | union { |
80 | llvm::codeview::ClassRecord cvclass; |
81 | llvm::codeview::EnumRecord cvenum; |
82 | llvm::codeview::UnionRecord cvunion; |
83 | }; |
84 | Kind m_kind; |
85 | }; |
86 | |
87 | struct SegmentOffset { |
88 | SegmentOffset() = default; |
89 | SegmentOffset(uint16_t s, uint32_t o) : segment(s), offset(o) {} |
90 | uint16_t segment = 0; |
91 | uint32_t offset = 0; |
92 | }; |
93 | |
94 | struct SegmentOffsetLength { |
95 | SegmentOffsetLength() = default; |
96 | SegmentOffsetLength(uint16_t s, uint32_t o, uint32_t l) |
97 | : so(s, o), length(l) {} |
98 | SegmentOffset so; |
99 | uint32_t length = 0; |
100 | }; |
101 | |
102 | struct VariableInfo { |
103 | llvm::StringRef name; |
104 | llvm::codeview::TypeIndex type; |
105 | DWARFExpressionList location; |
106 | bool is_param; |
107 | }; |
108 | |
109 | llvm::pdb::PDB_SymType CVSymToPDBSym(llvm::codeview::SymbolKind kind); |
110 | llvm::pdb::PDB_SymType CVTypeToPDBType(llvm::codeview::TypeLeafKind kind); |
111 | |
112 | bool SymbolHasAddress(const llvm::codeview::CVSymbol &sym); |
113 | bool SymbolIsCode(const llvm::codeview::CVSymbol &sym); |
114 | |
115 | SegmentOffset GetSegmentAndOffset(const llvm::codeview::CVSymbol &sym); |
116 | SegmentOffsetLength |
117 | GetSegmentOffsetAndLength(const llvm::codeview::CVSymbol &sym); |
118 | |
119 | template <typename RecordT> bool IsValidRecord(const RecordT &sym) { |
120 | return true; |
121 | } |
122 | |
123 | inline bool IsValidRecord(const llvm::codeview::ProcRefSym &sym) { |
124 | // S_PROCREF symbols have 1-based module indices. |
125 | return sym.Module > 0; |
126 | } |
127 | |
128 | bool IsForwardRefUdt(llvm::codeview::CVType cvt); |
129 | bool IsTagRecord(llvm::codeview::CVType cvt); |
130 | bool IsClassStructUnion(llvm::codeview::CVType cvt); |
131 | |
132 | bool IsForwardRefUdt(const PdbTypeSymId &id, llvm::pdb::TpiStream &tpi); |
133 | bool IsTagRecord(const PdbTypeSymId &id, llvm::pdb::TpiStream &tpi); |
134 | |
135 | lldb::AccessType TranslateMemberAccess(llvm::codeview::MemberAccess access); |
136 | llvm::codeview::TypeIndex GetFieldListIndex(llvm::codeview::CVType cvt); |
137 | llvm::codeview::TypeIndex |
138 | LookThroughModifierRecord(llvm::codeview::CVType modifier); |
139 | |
140 | llvm::StringRef DropNameScope(llvm::StringRef name); |
141 | |
142 | VariableInfo GetVariableNameInfo(llvm::codeview::CVSymbol symbol); |
143 | VariableInfo GetVariableLocationInfo(PdbIndex &index, PdbCompilandSymId var_id, |
144 | Block &func_block, lldb::ModuleSP module); |
145 | |
146 | size_t GetTypeSizeForSimpleKind(llvm::codeview::SimpleTypeKind kind); |
147 | lldb::BasicType |
148 | GetCompilerTypeForSimpleKind(llvm::codeview::SimpleTypeKind kind); |
149 | |
150 | PdbTypeSymId GetBestPossibleDecl(PdbTypeSymId id, llvm::pdb::TpiStream &tpi); |
151 | |
152 | size_t GetSizeOfType(PdbTypeSymId id, llvm::pdb::TpiStream &tpi); |
153 | |
154 | } // namespace npdb |
155 | } // namespace lldb_private |
156 | |
157 | #endif |
158 | |