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