1343181Sdim//===-- PdbUtil.h -----------------------------------------------*- C++ -*-===//
2343181Sdim//
3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4353358Sdim// See https://llvm.org/LICENSE.txt for license information.
5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6343181Sdim//
7343181Sdim//===----------------------------------------------------------------------===//
8343181Sdim
9343181Sdim#ifndef LLDB_PLUGINS_SYMBOLFILENATIVEPDB_PDBUTIL_H
10343181Sdim#define LLDB_PLUGINS_SYMBOLFILENATIVEPDB_PDBUTIL_H
11343181Sdim
12343181Sdim#include "lldb/Expression/DWARFExpression.h"
13343181Sdim#include "lldb/Symbol/Variable.h"
14343181Sdim#include "lldb/lldb-enumerations.h"
15343181Sdim
16343181Sdim#include "llvm/ADT/Optional.h"
17343181Sdim#include "llvm/DebugInfo/CodeView/CodeView.h"
18343181Sdim#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
19343181Sdim#include "llvm/DebugInfo/CodeView/TypeRecord.h"
20343181Sdim#include "llvm/DebugInfo/PDB/PDBTypes.h"
21343181Sdim
22343181Sdim#include "PdbSymUid.h"
23343181Sdim
24343181Sdim#include <tuple>
25343181Sdim#include <utility>
26343181Sdim
27343181Sdimnamespace llvm {
28343181Sdimnamespace pdb {
29343181Sdimclass TpiStream;
30343181Sdim}
31343181Sdim} // namespace llvm
32343181Sdim
33343181Sdimnamespace lldb_private {
34343181Sdimnamespace npdb {
35343181Sdim
36343181Sdimclass PdbIndex;
37343181Sdim
38343181Sdimstruct CVTagRecord {
39343181Sdim  enum Kind { Class, Struct, Union, Enum };
40343181Sdim
41343181Sdim  static CVTagRecord create(llvm::codeview::CVType type);
42343181Sdim
43343181Sdim  Kind kind() const { return m_kind; }
44343181Sdim
45343181Sdim  const llvm::codeview::TagRecord &asTag() const {
46343181Sdim    if (m_kind == Struct || m_kind == Class)
47343181Sdim      return cvclass;
48343181Sdim    if (m_kind == Enum)
49343181Sdim      return cvenum;
50343181Sdim    return cvunion;
51343181Sdim  }
52343181Sdim
53343181Sdim  const llvm::codeview::ClassRecord &asClass() const {
54343181Sdim    assert(m_kind == Struct || m_kind == Class);
55343181Sdim    return cvclass;
56343181Sdim  }
57343181Sdim
58343181Sdim  const llvm::codeview::EnumRecord &asEnum() const {
59343181Sdim    assert(m_kind == Enum);
60343181Sdim    return cvenum;
61343181Sdim  }
62343181Sdim
63343181Sdim  const llvm::codeview::UnionRecord &asUnion() const {
64343181Sdim    assert(m_kind == Union);
65343181Sdim    return cvunion;
66343181Sdim  }
67343181Sdim
68343181Sdim  llvm::StringRef name() const {
69343181Sdim    if (m_kind == Struct || m_kind == Union)
70343181Sdim      return cvclass.Name;
71343181Sdim    if (m_kind == Enum)
72343181Sdim      return cvenum.Name;
73343181Sdim    return cvunion.Name;
74343181Sdim  }
75343181Sdim
76343181Sdimprivate:
77343181Sdim  CVTagRecord(llvm::codeview::ClassRecord &&c);
78343181Sdim  CVTagRecord(llvm::codeview::UnionRecord &&u);
79343181Sdim  CVTagRecord(llvm::codeview::EnumRecord &&e);
80343181Sdim  union {
81343181Sdim    llvm::codeview::ClassRecord cvclass;
82343181Sdim    llvm::codeview::EnumRecord cvenum;
83343181Sdim    llvm::codeview::UnionRecord cvunion;
84343181Sdim  };
85343181Sdim  Kind m_kind;
86343181Sdim};
87343181Sdim
88343181Sdimstruct SegmentOffset {
89343181Sdim  SegmentOffset() = default;
90343181Sdim  SegmentOffset(uint16_t s, uint32_t o) : segment(s), offset(o) {}
91343181Sdim  uint16_t segment = 0;
92343181Sdim  uint32_t offset = 0;
93343181Sdim};
94343181Sdim
95343181Sdimstruct SegmentOffsetLength {
96343181Sdim  SegmentOffsetLength() = default;
97343181Sdim  SegmentOffsetLength(uint16_t s, uint32_t o, uint32_t l)
98343181Sdim      : so(s, o), length(l) {}
99343181Sdim  SegmentOffset so;
100343181Sdim  uint32_t length = 0;
101343181Sdim};
102343181Sdim
103343181Sdimstruct VariableInfo {
104343181Sdim  llvm::StringRef name;
105343181Sdim  llvm::codeview::TypeIndex type;
106343181Sdim  llvm::Optional<DWARFExpression> location;
107343181Sdim  llvm::Optional<Variable::RangeList> ranges;
108343181Sdim};
109343181Sdim
110343181Sdimllvm::pdb::PDB_SymType CVSymToPDBSym(llvm::codeview::SymbolKind kind);
111343181Sdimllvm::pdb::PDB_SymType CVTypeToPDBType(llvm::codeview::TypeLeafKind kind);
112343181Sdim
113343181Sdimbool SymbolHasAddress(const llvm::codeview::CVSymbol &sym);
114343181Sdimbool SymbolIsCode(const llvm::codeview::CVSymbol &sym);
115343181Sdim
116343181SdimSegmentOffset GetSegmentAndOffset(const llvm::codeview::CVSymbol &sym);
117343181SdimSegmentOffsetLength
118343181SdimGetSegmentOffsetAndLength(const llvm::codeview::CVSymbol &sym);
119343181Sdim
120343181Sdimtemplate <typename RecordT> bool IsValidRecord(const RecordT &sym) {
121343181Sdim  return true;
122343181Sdim}
123343181Sdim
124343181Sdiminline bool IsValidRecord(const llvm::codeview::ProcRefSym &sym) {
125343181Sdim  // S_PROCREF symbols have 1-based module indices.
126343181Sdim  return sym.Module > 0;
127343181Sdim}
128343181Sdim
129343181Sdimbool IsForwardRefUdt(llvm::codeview::CVType cvt);
130343181Sdimbool IsTagRecord(llvm::codeview::CVType cvt);
131343181Sdimbool IsClassStructUnion(llvm::codeview::CVType cvt);
132343181Sdim
133343181Sdimbool IsForwardRefUdt(const PdbTypeSymId &id, llvm::pdb::TpiStream &tpi);
134343181Sdimbool IsTagRecord(const PdbTypeSymId &id, llvm::pdb::TpiStream &tpi);
135343181Sdim
136343181Sdimlldb::AccessType TranslateMemberAccess(llvm::codeview::MemberAccess access);
137343181Sdimllvm::codeview::TypeIndex GetFieldListIndex(llvm::codeview::CVType cvt);
138343181Sdimllvm::codeview::TypeIndex
139343181SdimLookThroughModifierRecord(llvm::codeview::CVType modifier);
140343181Sdim
141343181Sdimllvm::StringRef DropNameScope(llvm::StringRef name);
142343181Sdim
143343181SdimVariableInfo GetVariableNameInfo(llvm::codeview::CVSymbol symbol);
144353358SdimVariableInfo GetVariableLocationInfo(PdbIndex &index, PdbCompilandSymId var_id, Block& block,
145343181Sdim                                     lldb::ModuleSP module);
146343181Sdim
147343181Sdimsize_t GetTypeSizeForSimpleKind(llvm::codeview::SimpleTypeKind kind);
148343181Sdimlldb::BasicType
149343181SdimGetCompilerTypeForSimpleKind(llvm::codeview::SimpleTypeKind kind);
150343181Sdim
151343181SdimPdbTypeSymId GetBestPossibleDecl(PdbTypeSymId id, llvm::pdb::TpiStream &tpi);
152343181Sdim
153343181Sdimsize_t GetSizeOfType(PdbTypeSymId id, llvm::pdb::TpiStream &tpi);
154343181Sdim
155343181Sdim} // namespace npdb
156343181Sdim} // namespace lldb_private
157343181Sdim
158343181Sdim#endif
159