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/lldb-enumerations.h"
14 
15 #include "llvm/DebugInfo/CodeView/SymbolRecord.h"
16 #include "llvm/DebugInfo/CodeView/TypeRecord.h"
17 #include "llvm/DebugInfo/PDB/PDBTypes.h"
18 
19 #include <tuple>
20 #include <utility>
21 
22 namespace llvm {
23 namespace pdb {
24 class TpiStream;
25 }
26 } // namespace llvm
27 
28 namespace lldb_private {
29 namespace npdb {
30 
31 struct PdbTypeSymId;
32 
33 struct CVTagRecord {
34   enum Kind { Class, Struct, Union, Enum };
35 
36   static CVTagRecord create(llvm::codeview::CVType type);
37 
38   Kind kind() const { return m_kind; }
39 
40   const llvm::codeview::TagRecord &asTag() const {
41     if (m_kind == Struct || m_kind == Class)
42       return cvclass;
43     if (m_kind == Enum)
44       return cvenum;
45     return cvunion;
46   }
47 
48   const llvm::codeview::ClassRecord &asClass() const {
49     assert(m_kind == Struct || m_kind == Class);
50     return cvclass;
51   }
52 
53   const llvm::codeview::EnumRecord &asEnum() const {
54     assert(m_kind == Enum);
55     return cvenum;
56   }
57 
58   const llvm::codeview::UnionRecord &asUnion() const {
59     assert(m_kind == Union);
60     return cvunion;
61   }
62 
63 private:
64   CVTagRecord(llvm::codeview::ClassRecord &&c);
65   CVTagRecord(llvm::codeview::UnionRecord &&u);
66   CVTagRecord(llvm::codeview::EnumRecord &&e);
67   union {
68     llvm::codeview::ClassRecord cvclass;
69     llvm::codeview::EnumRecord cvenum;
70     llvm::codeview::UnionRecord cvunion;
71   };
72   Kind m_kind;
73 };
74 
75 struct SegmentOffset {
76   SegmentOffset() = default;
77   SegmentOffset(uint16_t s, uint32_t o) : segment(s), offset(o) {}
78   uint16_t segment = 0;
79   uint32_t offset = 0;
80 };
81 
82 struct SegmentOffsetLength {
83   SegmentOffsetLength() = default;
84   SegmentOffsetLength(uint16_t s, uint32_t o, uint32_t l)
85       : so(s, o), length(l) {}
86   SegmentOffset so;
87   uint32_t length = 0;
88 };
89 
90 llvm::pdb::PDB_SymType CVSymToPDBSym(llvm::codeview::SymbolKind kind);
91 llvm::pdb::PDB_SymType CVTypeToPDBType(llvm::codeview::TypeLeafKind kind);
92 
93 bool SymbolHasAddress(const llvm::codeview::CVSymbol &sym);
94 bool SymbolIsCode(const llvm::codeview::CVSymbol &sym);
95 
96 SegmentOffset GetSegmentAndOffset(const llvm::codeview::CVSymbol &sym);
97 SegmentOffsetLength
98 GetSegmentOffsetAndLength(const llvm::codeview::CVSymbol &sym);
99 
100 template <typename RecordT> bool IsValidRecord(const RecordT &sym) {
101   return true;
102 }
103 
104 inline bool IsValidRecord(const llvm::codeview::ProcRefSym &sym) {
105   // S_PROCREF symbols have 1-based module indices.
106   return sym.Module > 0;
107 }
108 
109 bool IsForwardRefUdt(llvm::codeview::CVType cvt);
110 bool IsTagRecord(llvm::codeview::CVType cvt);
111 
112 bool IsForwardRefUdt(const PdbTypeSymId &id, llvm::pdb::TpiStream &tpi);
113 bool IsTagRecord(const PdbTypeSymId &id, llvm::pdb::TpiStream &tpi);
114 
115 lldb::AccessType TranslateMemberAccess(llvm::codeview::MemberAccess access);
116 llvm::codeview::TypeIndex GetFieldListIndex(llvm::codeview::CVType cvt);
117 llvm::codeview::TypeIndex
118 LookThroughModifierRecord(llvm::codeview::CVType modifier);
119 
120 llvm::StringRef DropNameScope(llvm::StringRef name);
121 
122 } // namespace npdb
123 } // namespace lldb_private
124 
125 #endif
126