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