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