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