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