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_PLUGINS_SYMBOLFILENATIVEPDB_PDBUTIL_H
10#define LLDB_PLUGINS_SYMBOLFILENATIVEPDB_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
27namespace llvm {
28namespace pdb {
29class TpiStream;
30}
31} // namespace llvm
32
33namespace lldb_private {
34namespace npdb {
35
36class PdbIndex;
37
38struct 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
76private:
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
88struct 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
95struct 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
103struct VariableInfo {
104  llvm::StringRef name;
105  llvm::codeview::TypeIndex type;
106  llvm::Optional<DWARFExpression> location;
107  llvm::Optional<Variable::RangeList> ranges;
108};
109
110llvm::pdb::PDB_SymType CVSymToPDBSym(llvm::codeview::SymbolKind kind);
111llvm::pdb::PDB_SymType CVTypeToPDBType(llvm::codeview::TypeLeafKind kind);
112
113bool SymbolHasAddress(const llvm::codeview::CVSymbol &sym);
114bool SymbolIsCode(const llvm::codeview::CVSymbol &sym);
115
116SegmentOffset GetSegmentAndOffset(const llvm::codeview::CVSymbol &sym);
117SegmentOffsetLength
118GetSegmentOffsetAndLength(const llvm::codeview::CVSymbol &sym);
119
120template <typename RecordT> bool IsValidRecord(const RecordT &sym) {
121  return true;
122}
123
124inline bool IsValidRecord(const llvm::codeview::ProcRefSym &sym) {
125  // S_PROCREF symbols have 1-based module indices.
126  return sym.Module > 0;
127}
128
129bool IsForwardRefUdt(llvm::codeview::CVType cvt);
130bool IsTagRecord(llvm::codeview::CVType cvt);
131bool IsClassStructUnion(llvm::codeview::CVType cvt);
132
133bool IsForwardRefUdt(const PdbTypeSymId &id, llvm::pdb::TpiStream &tpi);
134bool IsTagRecord(const PdbTypeSymId &id, llvm::pdb::TpiStream &tpi);
135
136lldb::AccessType TranslateMemberAccess(llvm::codeview::MemberAccess access);
137llvm::codeview::TypeIndex GetFieldListIndex(llvm::codeview::CVType cvt);
138llvm::codeview::TypeIndex
139LookThroughModifierRecord(llvm::codeview::CVType modifier);
140
141llvm::StringRef DropNameScope(llvm::StringRef name);
142
143VariableInfo GetVariableNameInfo(llvm::codeview::CVSymbol symbol);
144VariableInfo GetVariableLocationInfo(PdbIndex &index, PdbCompilandSymId var_id, Block& block,
145                                     lldb::ModuleSP module);
146
147size_t GetTypeSizeForSimpleKind(llvm::codeview::SimpleTypeKind kind);
148lldb::BasicType
149GetCompilerTypeForSimpleKind(llvm::codeview::SimpleTypeKind kind);
150
151PdbTypeSymId GetBestPossibleDecl(PdbTypeSymId id, llvm::pdb::TpiStream &tpi);
152
153size_t GetSizeOfType(PdbTypeSymId id, llvm::pdb::TpiStream &tpi);
154
155} // namespace npdb
156} // namespace lldb_private
157
158#endif
159