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
26namespace llvm {
27namespace pdb {
28class TpiStream;
29}
30} // namespace llvm
31
32namespace lldb_private {
33namespace npdb {
34
35class PdbIndex;
36
37struct CVTagRecord {
38  enum Kind { Class, Struct, Union, Enum };
39
40  static CVTagRecord create(llvm::codeview::CVType type);
41
42  Kind kind() const { return m_kind; }
43
44  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
52  const llvm::codeview::ClassRecord &asClass() const {
53    assert(m_kind == Struct || m_kind == Class);
54    return cvclass;
55  }
56
57  const llvm::codeview::EnumRecord &asEnum() const {
58    assert(m_kind == Enum);
59    return cvenum;
60  }
61
62  const llvm::codeview::UnionRecord &asUnion() const {
63    assert(m_kind == Union);
64    return cvunion;
65  }
66
67  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
75private:
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
87struct SegmentOffset {
88  SegmentOffset() = default;
89  SegmentOffset(uint16_t s, uint32_t o) : segment(s), offset(o) {}
90  uint16_t segment = 0;
91  uint32_t offset = 0;
92};
93
94struct SegmentOffsetLength {
95  SegmentOffsetLength() = default;
96  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
102struct VariableInfo {
103  llvm::StringRef name;
104  llvm::codeview::TypeIndex type;
105  DWARFExpressionList location;
106  bool is_param;
107};
108
109llvm::pdb::PDB_SymType CVSymToPDBSym(llvm::codeview::SymbolKind kind);
110llvm::pdb::PDB_SymType CVTypeToPDBType(llvm::codeview::TypeLeafKind kind);
111
112bool SymbolHasAddress(const llvm::codeview::CVSymbol &sym);
113bool SymbolIsCode(const llvm::codeview::CVSymbol &sym);
114
115SegmentOffset GetSegmentAndOffset(const llvm::codeview::CVSymbol &sym);
116SegmentOffsetLength
117GetSegmentOffsetAndLength(const llvm::codeview::CVSymbol &sym);
118
119template <typename RecordT> bool IsValidRecord(const RecordT &sym) {
120  return true;
121}
122
123inline bool IsValidRecord(const llvm::codeview::ProcRefSym &sym) {
124  // S_PROCREF symbols have 1-based module indices.
125  return sym.Module > 0;
126}
127
128bool IsForwardRefUdt(llvm::codeview::CVType cvt);
129bool IsTagRecord(llvm::codeview::CVType cvt);
130bool IsClassStructUnion(llvm::codeview::CVType cvt);
131
132bool IsForwardRefUdt(const PdbTypeSymId &id, llvm::pdb::TpiStream &tpi);
133bool IsTagRecord(const PdbTypeSymId &id, llvm::pdb::TpiStream &tpi);
134
135lldb::AccessType TranslateMemberAccess(llvm::codeview::MemberAccess access);
136llvm::codeview::TypeIndex GetFieldListIndex(llvm::codeview::CVType cvt);
137llvm::codeview::TypeIndex
138LookThroughModifierRecord(llvm::codeview::CVType modifier);
139
140llvm::StringRef DropNameScope(llvm::StringRef name);
141
142VariableInfo GetVariableNameInfo(llvm::codeview::CVSymbol symbol);
143VariableInfo GetVariableLocationInfo(PdbIndex &index, PdbCompilandSymId var_id,
144                                     Block &func_block, lldb::ModuleSP module);
145
146size_t GetTypeSizeForSimpleKind(llvm::codeview::SimpleTypeKind kind);
147lldb::BasicType
148GetCompilerTypeForSimpleKind(llvm::codeview::SimpleTypeKind kind);
149
150PdbTypeSymId GetBestPossibleDecl(PdbTypeSymId id, llvm::pdb::TpiStream &tpi);
151
152size_t GetSizeOfType(PdbTypeSymId id, llvm::pdb::TpiStream &tpi);
153
154} // namespace npdb
155} // namespace lldb_private
156
157#endif
158