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 
43   Kind kind() const { return m_kind; }
44 
45   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 
53   const llvm::codeview::ClassRecord &asClass() const {
54     assert(m_kind == Struct || m_kind == Class);
55     return cvclass;
56   }
57 
58   const llvm::codeview::EnumRecord &asEnum() const {
59     assert(m_kind == Enum);
60     return cvenum;
61   }
62 
63   const llvm::codeview::UnionRecord &asUnion() const {
64     assert(m_kind == Union);
65     return cvunion;
66   }
67 
68   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;
90   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;
97   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   bool is_param;
109 };
110 
111 llvm::pdb::PDB_SymType CVSymToPDBSym(llvm::codeview::SymbolKind kind);
112 llvm::pdb::PDB_SymType CVTypeToPDBType(llvm::codeview::TypeLeafKind kind);
113 
114 bool SymbolHasAddress(const llvm::codeview::CVSymbol &sym);
115 bool SymbolIsCode(const llvm::codeview::CVSymbol &sym);
116 
117 SegmentOffset GetSegmentAndOffset(const llvm::codeview::CVSymbol &sym);
118 SegmentOffsetLength
119 GetSegmentOffsetAndLength(const llvm::codeview::CVSymbol &sym);
120 
121 template <typename RecordT> bool IsValidRecord(const RecordT &sym) {
122   return true;
123 }
124 
125 inline bool IsValidRecord(const llvm::codeview::ProcRefSym &sym) {
126   // S_PROCREF symbols have 1-based module indices.
127   return sym.Module > 0;
128 }
129 
130 bool IsForwardRefUdt(llvm::codeview::CVType cvt);
131 bool IsTagRecord(llvm::codeview::CVType cvt);
132 bool IsClassStructUnion(llvm::codeview::CVType cvt);
133 
134 bool IsForwardRefUdt(const PdbTypeSymId &id, llvm::pdb::TpiStream &tpi);
135 bool IsTagRecord(const PdbTypeSymId &id, llvm::pdb::TpiStream &tpi);
136 
137 lldb::AccessType TranslateMemberAccess(llvm::codeview::MemberAccess access);
138 llvm::codeview::TypeIndex GetFieldListIndex(llvm::codeview::CVType cvt);
139 llvm::codeview::TypeIndex
140 LookThroughModifierRecord(llvm::codeview::CVType modifier);
141 
142 llvm::StringRef DropNameScope(llvm::StringRef name);
143 
144 VariableInfo GetVariableNameInfo(llvm::codeview::CVSymbol symbol);
145 VariableInfo GetVariableLocationInfo(PdbIndex &index, PdbCompilandSymId var_id,
146                                      Block &func_block, lldb::ModuleSP module);
147 
148 size_t GetTypeSizeForSimpleKind(llvm::codeview::SimpleTypeKind kind);
149 lldb::BasicType
150 GetCompilerTypeForSimpleKind(llvm::codeview::SimpleTypeKind kind);
151 
152 PdbTypeSymId GetBestPossibleDecl(PdbTypeSymId id, llvm::pdb::TpiStream &tpi);
153 
154 size_t GetSizeOfType(PdbTypeSymId id, llvm::pdb::TpiStream &tpi);
155 
156 } // namespace npdb
157 } // namespace lldb_private
158 
159 #endif
160