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 
kindCVTagRecord42   Kind kind() const { return m_kind; }
43 
asTagCVTagRecord44   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 
asClassCVTagRecord52   const llvm::codeview::ClassRecord &asClass() const {
53     assert(m_kind == Struct || m_kind == Class);
54     return cvclass;
55   }
56 
asEnumCVTagRecord57   const llvm::codeview::EnumRecord &asEnum() const {
58     assert(m_kind == Enum);
59     return cvenum;
60   }
61 
asUnionCVTagRecord62   const llvm::codeview::UnionRecord &asUnion() const {
63     assert(m_kind == Union);
64     return cvunion;
65   }
66 
nameCVTagRecord67   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;
SegmentOffsetSegmentOffset89   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;
SegmentOffsetLengthSegmentOffsetLength96   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 
IsValidRecord(const RecordT & sym)119 template <typename RecordT> bool IsValidRecord(const RecordT &sym) {
120   return true;
121 }
122 
IsValidRecord(const llvm::codeview::ProcRefSym & sym)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